Page 1 of 1

Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Mon Aug 01, 2016 10:46 am
by PacManPlus
Hi:

Just a curiosity question here. I am porting a game that I developed (an arcade port) on the Atari 7800 over to the NES. I'd like to use the same sounds that I created on the 7800, but I am having great difficulty. (The Atari 7800 uses the same TIA as the Atari 2600)

I've adapted the sound driver that I used for the 7800 TIA over to the NES, and expanded it (from the 2 channels of the TIA to the 4 - two square, one triangle and one noise) for the 2A03.

Is there any conversion chart available for notes and noises from one to the other? I did a Google search but found nothing. :(
I understand they won't sound exactly the same of course... I was hoping for 'close enough'. :)

Thank you for your help...
Bob

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Mon Aug 01, 2016 10:52 am
by dougeff
I think you could fit every 7800 programmer in the world in a small closet. You might literally be the only person who's considering porting music from 7800 to NES.

You may have to start from scratch.

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Mon Aug 01, 2016 10:55 am
by PacManPlus
dougeff wrote:I think you could fit every 7800 programmer in the world in a small closet. You might literally be the only person who's considering porting music from 7800 to NES.

You may have to start from scratch.
Lol, I know. I've done a bunch of arcade ports to the 7800: Astro Fighter, Astro Blaster, Jr. Pac-Man, Super Pac-Man, Rip-Off, Scramble, Berzerk/Frenzy (this is the one I'm trying to port to the NES - I'm just down to sound), Space Duel, Asteroids Deluxe, Space Invaders, etc.. and some 'originals'.
That's why I mentioned that it uses the same sound chip as the 2600. ;)

Thanks,
Bob

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Mon Aug 01, 2016 11:14 am
by mikejmoffitt
Principally, aren't both chips implementing the notes as periods to load a counter with? You should be able to apply some coefficient to your load values (and the 2A03 channels are 11-bit, not the 8-bit resolution of the TIA ones) and then it may "just work".

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Mon Aug 01, 2016 11:47 am
by PacManPlus
Ok, I found a TIA note chart, so I'll look for a 2A03 note chart as well and do the connections myself.

This wasn't my major concern, however, as sound effects make up 99% of the audio (I just have one short tune at the splash screen). I liked the sounds I had come up with on the 7800 for the shot, explosion, and death, and I wanted to approximate them as close as possible here. If anyone can help with that, it would be great. I dislike re-inventing the wheel.

I also have the voice sample data that I used for the 7800 version as well, and I'll use some of it here once I figure out the Digital channel. The only thing is I'll be cutting some of the speech out as I don't have room for it all (it's 22K for the speech data alone on the 7800 version). I'm trying to keep this at Mapper 0 so as you know I only have 32K total.

Thanks,
Bob

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Mon Aug 01, 2016 12:29 pm
by lidnariq
As you know, the TIA has two channels; each with its own 4-bit volume channel and its own 5-bit frequency divider. Additionally, each channel is limited to one of 16 [tone color and additional frequency divider] choices.

So, ignoring tone color, you can convert the frequency divider (AUDFx) and tone color (AUDCx) to a pure frequency by saying
31400Hz ÷ (AUDFx+1) ÷ table[AUDCx] (table[n] is [inf,15,465,465,2,2,31,31,511,31,31,inf,6,6,93,93].)
In contrast, the NES's pulse wave frequencies are the simpler
111861Hz ÷ divider
and its triangle wave is that÷2.

The math is straightforward, at that point.

Now, compensating for tone color is a good deal more annoying.
Each of the TIA's channels can produce one of eight different tone colors. The NES's tone colors are divided more by channel:
• The two pulse wave channels can make one of three tone colors.
• The triangle channel can make one tone color, but approximately has no volume control
• The noise channel can make two tone colors, but one is random.

Sitting down with the 2600 docs and an FFT, the mapping is approximately:
AUDCx=0,B - silence
AUDCx=1 - LFSR equivalent to 1/15th duty pulse wave; closest match is pulse wave channel 1/8th duty
AUDCx=2 - very approximately the same as =1
AUDCx=3 - too complex for an analog
AUDCx=4,5,C,D - square wave. NES pulse waves support identical
AUDCx=6,A,E - 42% or 68% duty cycle pulse wave. Equally close to the NES's 1/4 and 1/2 duty cycle pulse.
AUDCx=7,9,F - LFSR equivalent to 1/31st duty pulse wave; no good match on the NES (closest is again 1/8th)
AUDCx=8 - 9-bit LFSR white noise. Closest is NES's 15-bit LFSR white noise


There's also this document from someone who used a 2600 as an instrument in a band.

edit#1: give up on summarizing AUDCx=3
edit#2: fix off-by-one
edit#3: fix typo of register name

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Mon Aug 01, 2016 12:40 pm
by PacManPlus
This is awesome - thank you so much! :)

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Tue Aug 02, 2016 5:58 pm
by PacManPlus
Ugh.

I am so lost with this. The TIA and even the Pokey is so straight-forward when making music / sound effects, and the 2A03 is so.... not.

I was trying to use the FamiTracker to get a sound (I downloaded some sound effects from the web), and I tried to convert them to the sound driver I'm using (I have a custom sound driver which I adapted from what I use for the TIA).

This is a quick description of how it is coded:
It reads 3 bytes per delta - Control/Volume, Note Low Byte, Frame Count / Note High Byte
Being that I'm using the Noise Channel, I am ignoring the 'Control' part of the first byte, and just using the Volume ORAing it with #$30 to turn off internal counters and writing that to $400C.
I am writing the second byte (the Sound Low Byte) to $400E.
I am extracting the Frame Count from the 2nd byte, so I know how many frames to play the current sound. There are only 16 sound types, so I am ignoring the Note High Byte from here.
I read somewhere on here that we have to put a non-zero byte in $400F, so I am forcing a '$01' there.

I am trying to get this data written as an example (so I know how to convert the sounds to my driver):

Code: Select all

PATTERN 00
ROW 00 : ... .. . ... : ... .. . ... : ... .. . ... : 5-# 00 D F01 : ... .. . ...
ROW 01 : ... .. . ... : ... .. . ... : ... .. . ... : 4-# 00 C ... : ... .. . ...
ROW 02 : ... .. . ... : ... .. . ... : ... .. . ... : 3-# 00 B F02 : ... .. . ...
ROW 03 : ... .. . ... : ... .. . ... : ... .. . ... : 2-# 00 A ... : ... .. . ...
ROW 04 : ... .. . ... : ... .. . ... : ... .. . ... : 1-# 00 9 F03 : ... .. . ...
ROW 05 : ... .. . ... : ... .. . ... : ... .. . ... : 0-# 00 8 ... : ... .. . ...
ROW 06 : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 7 F04 : ... .. . ...
ROW 07 : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 6 ... : ... .. . ...
ROW 08 : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 5 F05 : ... .. . ...
ROW 09 : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 4 ... : ... .. . ...
ROW 0A : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 3 F06 : ... .. . ...
ROW 0B : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 2 ... : ... .. . ...
ROW 0C : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 1 F07 : ... .. . ...
ROW 0D : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 0 ... : ... .. . ...
ROW 0E : ... .. . ... : ... .. . ... : ... .. . ... : ... .. . ... : ... .. . ...
ROW 0F : ... .. . ... : ... .. . ... : ... .. . ... : ... .. . ... : ... .. . ...
This is how I am doing it for both TIA and Pokey, and it works there. For the 2A03, I seem to get only one sound (the shhhhhhhhhhhh sound).
I've tried the Low Bytes with and without the high bit set (for Mode-0 or Mode-1)

I've also checked the contents to make sure I was writing the values that I think I'm writing, and they are correct.
Does anyone know what I am doing wrong to not be able to get the sound like I've shown above?

This is my data:

Code: Select all

;	FREQUENCY LOW BYTE - LOW BYTE OF NOTE (LFTUNEXX)
;	FRAME/FREQUENCY - BIT 76543XXX CONTROL THE NUMBER OF FRAMES, BIT XXXXX210 CONTAIN THE HIGH BYTE OF NOTE (FHTUNEXX)
;	VOICE/VOLUME - BITS 76--XXXX CONTAIN THE VOICE CONTROL, BITS XX--3210 CONTAIN THE VOLUME (CVTUNEXX)
;	$00 IN ALL THREE BYTES ENDS THE SOUND
;	TEMPOS
T01	=	$00
T02	=	$08
T03	=	$10
T04	=	$18
T05	=	$20
T06	=	$28
T07	=	$30
T08	=	$38
LFTUNE02:
	.byte $05,$04,$03,$02,$01,$00,$00,$00
	.byte $00,$00,$00,$00,$00,$00,$00,$00
FHTUNE02:
	.byte T01,T01,T02,T02,T03,T03,T04,T04
	.byte T05,T05,T06,T06,T07,T07,$00,$00
CVTUNE02:
	.byte $0D,$0C,$0B,$0A,$09,$08,$07,$06
	.byte $05,$04,$03,$02,$01,$00,$00,$00
Thank you, thank you, thank you all for any help.
Bob

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Tue Aug 02, 2016 6:48 pm
by lidnariq
One: on the 2A03, white noise (analogous to AUDCn = 8) can only come out of the 4th ("noise") channel, and the 4th noise channel usually only produces white noise (the NES's noise channel has a tonal noise mode, but the harmonic content you get out is practically random: a function of the LFSR's exact contents when it's switched to tonal noise mode)

Two: The NES's white noise channel is fairly constrained. Unlike the two pulse wave channels and the triangle wave channel, it's restricted to one of sixteen frequencies ( http://wiki.nesdev.com/w/index.php/APU_Noise ).

LFSR white noise sources (like in the AY-8910, 2A03, VIC-1, SN76489, TIA) clocked at sample rate X are approximately equivalent to an ideal white noise source followed by a first-order lowpass filter at that same frequency.

So, with the TIA, the sixteen corner frequencies are 31400 Hz ÷ (1,2,3,…32) = (31400, 15700, 10466,…980)Hz, but on the NES it's restricted to instead a relatively constrained (and oddly musically related) set of periods going both much higher (rate 0 = period 4 = 447kHz) and lower (rate $F = period 4068 = 440Hz)

The NES noise channel periods corresponding to the TIA's range are values $4 ( rate 28kHz ≈ AUDFn=0@31kHz) through $E (rate 880Hz ≈ AUDFn=31@980Hz)

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Wed Aug 03, 2016 3:33 am
by PacManPlus
Thank you for that, and I think I get most of it, but I guess putting it into use is the part that I am not understanding.

I.E. my thing is, to get the above data:

Code: Select all

PATTERN 00
ROW 00 : ... .. . ... : ... .. . ... : ... .. . ... : 5-# 00 D F01 : ... .. . ...
ROW 01 : ... .. . ... : ... .. . ... : ... .. . ... : 4-# 00 C ... : ... .. . ...
ROW 02 : ... .. . ... : ... .. . ... : ... .. . ... : 3-# 00 B F02 : ... .. . ...
ROW 03 : ... .. . ... : ... .. . ... : ... .. . ... : 2-# 00 A ... : ... .. . ...
ROW 04 : ... .. . ... : ... .. . ... : ... .. . ... : 1-# 00 9 F03 : ... .. . ...
ROW 05 : ... .. . ... : ... .. . ... : ... .. . ... : 0-# 00 8 ... : ... .. . ...
ROW 06 : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 7 F04 : ... .. . ...
ROW 07 : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 6 ... : ... .. . ...
ROW 08 : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 5 F05 : ... .. . ...
ROW 09 : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 4 ... : ... .. . ...
ROW 0A : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 3 F06 : ... .. . ...
ROW 0B : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 2 ... : ... .. . ...
ROW 0C : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 1 F07 : ... .. . ...
ROW 0D : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 0 ... : ... .. . ...
ROW 0E : ... .. . ... : ... .. . ... : ... .. . ... : ... .. . ... : ... .. . ...
ROW 0F : ... .. . ... : ... .. . ... : ... .. . ... : ... .. . ... : ... .. . ...
What would be the bytes written to $400C and $400E (assuming $400F is constant at #$01)? I am not using the internal length counter (I have it disabled). I am keeping track of the number of frames myself, and writing to these registers once per frame. If I write what I *think* these values translate to (see my data in my previous post), I get just a 'plink' when mode = 1 and a 'shhhhhh' when mode = 0. In other words, nothing like what plays in Tracker.

I'm just trying to figure out what I am translating incorrectly.

Again, thank you, and I'm sorry that I am having a hard time with this. :(
Bob

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Wed Aug 03, 2016 5:22 am
by thefox
There's nothing too mystical about the noise channel if you disable the envelope and stop the length counter. Just make sure to reload the length counter after you stop it, so that it will have non-zero value.

Show some code, maybe?

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Wed Aug 03, 2016 4:01 pm
by PacManPlus
Thank you for the reply. Here is the sound code I am using (please remember, it's adapted from the TIA driver I use):

First, here is a video of the sound in FamiTracker, then what I get when I use 'Mode 0', and then 'Mode 1':
https://youtu.be/UUA6iNb8gFU

The sounds I will eventually try to replicate (once I figure this example out) are attached.

Code: Select all

;	TUNE ROUTINES ------------------------------------------------------------------------------------------------------------>

AUDC0T			EQU $4000						;Audio Control / Volume Channel 0
AUDF0T			EQU $4002						;Audio Frequency Channel 0

;	INITIALIZE SOUND HARDWARE
INITTUN
	LDA #$1F									;ENABLE ALL CHANNELS (SQUARE1, SQUARE2, TRIANGLE, NOISE, DIGITAL)
	STA $4015
	LDA #$00									;SILENCE ALL CHANNELS
	STA AUDF0T+$00
	STA AUDC0T+$00
	STA AUDF0T+$04
	STA AUDC0T+$04
	STA AUDF0T+$08
	STA AUDC0T+$08
	STA AUDF0T+$0C
	STA AUDC0T+$0C
	RTS

;	TURN OFF ALL SOUNDS
STOPTUN
	LDA #$00									;TURN OFF SOUNDS
	STA AUDF0T+$00
	STA AUDC0T+$00
	STA AUDF0T+$04
	STA AUDC0T+$04
	STA AUDF0T+$08
	STA AUDC0T+$08
	STA AUDF0T+$0C
	STA AUDC0T+$0C
	LDA #$01
	STA TUNOFF
	RTS

;	TURN ON ALL SOUNDS
STARTTUN
	LDA #$00
	STA TUNOFF
	RTS

;	THIS ROUTINE ERASES ALL TUNES
;	X AND Y ARE PRESERVED
CLEARTUN
	TXA											;STACK REGISTERS
	PHA
	TYA
	PHA
	LDX #$03
CTLOOP
	JSR ENDTUNE									;ERASE CURRENT TUNE
	DEX
	BPL CTLOOP
	PLA											;UNSTACK REGISTERS
	TAY
	PLA
	TAX
	RTS

;	ROUTINE TO KILL A PARTICULAR TUNE - IF IT IS RUNNING
;	INPUT: TUNE NUMBER IN A
;	X AND Y ARE PRESERVED
KILLTUNE
	STA TUNNUM									;SAVE IT
	TXA											;STACK REGISTERS
	PHA
	TYA
	PHA
	LDX #$03									;CHECK ALL CHANNELS
KTLOOP
	LDA TUNON,X									;SEE IF CHANNEL ON
	BEQ KTNEXT
	LDA TUNINDEX,X								;SEE IF HAS TUNE TO BE KILLED
	CMP TUNNUM
	BNE KTNEXT
	JSR ENDTUNE									;ERASE IT
KTNEXT
	DEX
	BPL KTLOOP
	PLA											;UNSTACK REGISTERS
	TAY
	PLA
	TAX
	RTS

;	THIS ROUTINE CLEARS OUT A TUNE CHANNEL
;	INPUT: X IS CHANNEL
ENDTUNE
	LDA #$00
	STA TUNON,X									;INDICATE CHANNEL CLEAR
	STA TUNINDEX,X								;CLEAR TUNE INDEX
	TXA
	ASL A
	ASL A
	TAY
	LDA #$00
	STA AUDF0T,Y								;SILENCE THE CHANNEL
	STA AUDC0T,Y
	RTS

;	THIS ROUTINE ENTERS A TUNE INTO ONE OF THE SOUND CHANNELS IF IT CAN
;	INPUT:  TUNE NUMBER IN A
;	X AND Y ARE PRESERVED
DOTUNE
	BMI DTEXIT									;$FF MEANS NO TUNE (FOR TABLE READS)
	STA TUNNUM									;SAVE IT
	;LDA AUTOPLAY								;IF IN AUTOPLAY - NO SOUND
	;BEQ DTCONT
	;RTS
DTCONT
	TXA											;STACK REGISTERS
	PHA
	TYA
	PHA
	LDY TUNNUM									;SEE IF WE CAN PUT IT IN
	LDX TUNCHANNL,Y								;GET WHAT CHANNEL TO TRY TO PUT IT IN
	LDA TUNON,X									;SEE IF CHANNEL OPEN
	BEQ DTDOIT
	LDA TUNPRIRTY,Y								;SEE IF WE CAN BUMP CHANNEL
	CMP TUNPRIOR,X
	BMI DTOUT
DTDOIT
	LDA TUNNUM
	TAY											;PUT TUNE IN Y
	STA TUNINDEX,X								;SET THE TUNE INDEX
	LDA #$00									;TURN TUNE OFF WHILE CHANGING IT
	STA TUNON,X
	LDA TUNLOWFRQL,Y							;GET LOW BYTE OF FREQUENCY LOW ADDRESS
	STA LOWFRQL,X
	LDA TUNLOWFRQH,Y							;GET LOW BYTE OF FREQUENCY HIGH ADDRESS
	STA LOWFRQH,X
	LDA TUNFRMFRQL,Y							;GET TUNE DURATION AND FREQUENCY LOW ADDRESS
	STA FRMFRQL,X
	LDA TUNFRMFRQH,Y							;GET TUNE DURATION AND FREQUENCY HIGH ADDRESS
	STA FRMFRQH,X
	LDA TUNCTLVOLL,Y							;GET TUNE CNTL AND VOLUME LOW ADDRESS
	STA CTLVOLL,X
	LDA TUNCTLVOLH,Y							;GET TUNE CNTL AND VOLUME HIGH ADDRESS
	STA CTLVOLH,X
	LDA TUNPRIRTY,Y								;SET PRIORITY
	STA TUNPRIOR,X
	LDA #$01									;SET FREQ, CTL, AND VOL TO BE SET
	STA TUNFRM,X
	STA TUNON,X									;AND TURN THE TUNE ON!
DTOUT
	PLA											;UNSTACK REGISTERS
	TAY
	PLA
	TAX
DTEXIT
	RTS

;	THIS ROUTINE IS CALLED EVERY VBLANK TO TAKE CARE OF TUNES
;	REGISTERS ARE NOT SAVED
TUNER
	LDX #$03									;TWO TUNES CHANNELS, START WITH LAST
	LDA TUNOFF
	BEQ TUNLOOP
	RTS
TUNLOOP
	LDA TUNON,X
	BNE TUNBODY
	TXA
	ASL A
	ASL A
	TAY
	LDA #$00
	STA AUDC0T,Y								;IF THE CHANNEL IS OFF - MAKE SURE VOLUME IS OFF
	JMP TUNNEXT
TUNBODY
	DEC TUNFRM,X								;SEE IF WE'RE DONE WITH THIS SOUND
	BEQ TUNCTLVOL
	JMP TUNNEXT									;NOPE, CONTINUE
TUNCTLVOL
	LDA CTLVOLL,X								;GET THE CURRENT DUTY CYCLE / VOLUME BYTE
	STA SOUNDZP
	LDA CTLVOLH,X
	STA SOUNDZP+1
	LDY #$00
	LDA [SOUNDZP],Y
	BEQ TUNEND									;$00 HERE MEANS END OF TUNE
	ORA #$30									;FORCE BITS 4 AND 5 TO BE ON (WE CONTROL FRAMES AND VOLUME)
	PHA
	TXA											;MAKE 'Y' AN INDEX INTO THE SOUND REGISTERS
	ASL A
	ASL A
	TAY
	PLA
	STA AUDC0T,Y								;STORE CONTROL
	INC CTLVOLL,X
	BNE TUNFRMFRQ
	INC CTLVOLH,X
TUNFRMFRQ
	LDY #$00
	LDA LOWFRQL,X								;GET THE LOW PERIOD ADDRESS
	STA SOUNDZP
	LDA LOWFRQH,X
	STA SOUNDZP+1
	LDA [SOUNDZP],Y								;NOW GET THE LOW BYTE OF THE PERIOD
	STA SOUNDTEMP
	LDA FRMFRQL,X								;GET THE DURATION / HIGH PERIOD ADDRESS
	STA SOUNDZP
	LDA FRMFRQH,X
	STA SOUNDZP+1
	LDA [SOUNDZP],Y								;GET THE CURRENT DURATION / HIGH PERIOD BYTE
	STA SOUNDTEMP+1
	TXA											;MAKE 'Y' AN INDEX INTO THE SOUND REGISTERS
	ASL A
	ASL A
	TAY
	LDA SOUNDTEMP
	STA AUDF0T,Y								;STORE FREQUENCY
	LDA SOUNDTEMP+1
	CPX #$03									;WE NEED TO WRITE A DUMMY VALUE TO $400F IF WE ARE ON THE NOISE CHANNEL
	BNE TUNNOTANOISE
	LDA #$01
TUNNOTANOISE
	AND #$07									;GET LOW THREE BITS OF THE HIGH FREQUENCY BYTE
	STA AUDF0T+1,Y

	CPX #$02									;IF TRIANGLE OR NOISE, SKIP THIS PART
	BPL TUNSKIPTN
	LDA #$08
	STA AUDC0T+1,Y
TUNSKIPTN
	LDA SOUNDTEMP+1								;NOW EXTRACT THE NUMBER OF FRAMES
	LSR A
	LSR A
	LSR A
	STA TUNFRM,X								;STORE DURATION (IN FRAMES)
	INC TUNFRM,X								;WE NEED THIS BECAUSE THE DURATION GETS DECREMENTED FIRST
	INC LOWFRQL,X								
	BNE TUNNXT1
	INC LOWFRQH,X
TUNNXT1
	INC FRMFRQL,X
	BNE TUNNEXT
	INC FRMFRQH,X
TUNNEXT
	DEX
	BMI TUNEXIT
	JMP TUNLOOP
TUNEXIT
	RTS

TUNEND
	LDA FRMFRQL,X								;SEE IF WE SHOULD REPEAT
	STA SOUNDZP
	LDA FRMFRQH,X
	STA SOUNDZP+1
	LDY #$00
	LDA [SOUNDZP],Y
	BMI TUNRESTART
	JSR ENDTUNE
	JMP TUNNEXT
TUNRESTART
	LDA TUNINDEX,X								;GET TUNE NUMBER
	TAY
	LDA TUNLOWFRQL,Y							;GET LOW BYTE OF FREQUENCY LOW ADDRESS
	STA LOWFRQL,X
	LDA TUNLOWFRQH,Y							;GET LOW BYTE OF FREQUENCY HIGH ADDRESS
	STA LOWFRQH,X
	LDA TUNFRMFRQL,Y							;GET TUNE DURATION AND FREQUENCY LOW ADDRESS
	STA FRMFRQL,X
	LDA TUNFRMFRQH,Y							;GET TUNE DURATION AND FREQUENCY HIGH ADDRESS
	STA FRMFRQH,X
	LDA TUNCTLVOLL,Y							;GET TUNE CNTL AND VOLUME LOW ADDRESS
	STA CTLVOLL,X
	LDA TUNCTLVOLH,Y							;GET TUNE CNTL AND VOLUME HIGH ADDRESS
	STA CTLVOLH,X
	LDA #$01									;SET FREQ, CTL, AND VOL TO BE SET
	STA TUNFRM,X
	JMP TUNNEXT

;	TUNE TABLES, BASE ADDRESSES FOR TUNES AND THE OFFSETS WITHIN THE TUNES WHERE
;	THE CTL AND VOL INFORMATION START
TUNLOWFRQL
	.byte LOW(LFTUNE00),LOW(LFTUNE01),LOW(LFTUNE02),LOW(LFTUNE03)
	.byte LOW(LFTUNE04),LOW(LFTUNE05),LOW(LFTUNE06),LOW(LFTUNE07)
	.byte LOW(LFTUNE08),LOW(LFTUNE09);,LOW(LFTUNE0A),LOW(LFTUNE0B)
TUNLOWFRQH
	.byte HIGH(LFTUNE00),HIGH(LFTUNE01),HIGH(LFTUNE02),HIGH(LFTUNE03)
	.byte HIGH(LFTUNE04),HIGH(LFTUNE05),HIGH(LFTUNE06),HIGH(LFTUNE07)
	.byte HIGH(LFTUNE08),HIGH(LFTUNE09);,HIGH(LFTUNE0A),HIGH(LFTUNE0B)

TUNFRMFRQL
	.byte LOW(FHTUNE00),LOW(FHTUNE01),LOW(FHTUNE02),LOW(FHTUNE03)
	.byte LOW(FHTUNE04),LOW(FHTUNE05),LOW(FHTUNE06),LOW(FHTUNE07)
	.byte LOW(FHTUNE08),LOW(FHTUNE09);,LOW(FHTUNE0A),LOW(FHTUNE0B)
TUNFRMFRQH
	.byte HIGH(FHTUNE00),HIGH(FHTUNE01),HIGH(FHTUNE02),HIGH(FHTUNE03)
	.byte HIGH(FHTUNE04),HIGH(FHTUNE05),HIGH(FHTUNE06),HIGH(FHTUNE07)
	.byte HIGH(FHTUNE08),HIGH(FHTUNE09);,HIGH(FHTUNE0A),HIGH(FHTUNE0B)

TUNCTLVOLL
	.byte LOW(CVTUNE00),LOW(CVTUNE01),LOW(CVTUNE02),LOW(CVTUNE03)
	.byte LOW(CVTUNE04),LOW(CVTUNE05),LOW(CVTUNE06),LOW(CVTUNE07)
	.byte LOW(CVTUNE08),LOW(CVTUNE09);,LOW(CVTUNE0A),LOW(CVTUNE0B)
TUNCTLVOLH
	.byte HIGH(CVTUNE00),HIGH(CVTUNE01),HIGH(CVTUNE02),HIGH(CVTUNE03)
	.byte HIGH(CVTUNE04),HIGH(CVTUNE05),HIGH(CVTUNE06),HIGH(CVTUNE07)
	.byte HIGH(CVTUNE08),HIGH(CVTUNE09);,HIGH(CVTUNE0A),HIGH(CVTUNE0B)

;	TUNE CHANNEL TABLE - DEFINES WHICH CHANNEL THE TUNE BELONGS IN, INDEXED BY TUNE NUMBER
TUNCHANNL
	.byte $00,$01,$03,$03,$00,$01,$01,$00
	.byte $00,$00,$00,$00,$00,$00,$00,$00

;	TUNE PRIORITTY TABLE - DEFINES WHICH TUNES HAVE PRIORITY OVER OTHERS, INDEXED BY TUNE NUMBER
TUNPRIRTY
	.byte $00,$00,$04,$04,$0D,$0D,$08,$04
	.byte $04,$0F,$00,$00,$00,$00,$00,$00

;	DATA FOR TUNES

;	PRIORITY - FOUND IN TABLE ABOVE, INDEXED BY TUNE NUMBER
;	CHANNEL - FOUND IN TABLE ABOVE, INDEXED BY TUNE NUMBER
;	FREQUENCY LOW BYTE - LOW BYTE OF NOTE (LFTUNEXX)
;	FRAME/FREQUENCY - BIT 76543XXX CONTROL THE NUMBER OF FRAMES, BIT XXXXX210 CONTAIN THE HIGH BYTE OF NOTE (FHTUNEXX)
;	VOICE/VOLUME - BIT 76--XXXX CONTAIN THE VOICE CONTROL, BIT XX--3210 CONTAIN THE VOLUME (CVTUNEXX)
;	$00 IN VOICE/VOLUME ENDS THE SOUND

;	TEMPOS
T01	=	$00
T02	=	$08
T03	=	$10
T04	=	$18
T05	=	$20
T06	=	$28
T07	=	$30
T08	=	$38

LFTUNE02:	; PLAYER SHOT
	.byte $05,$04,$03,$02,$01,$00,$00,$00
	.byte $00,$00,$00,$00,$00,$00,$00,$00
FHTUNE02:	; PLAYER SHOT
	.byte T01,T01,T02,T02,T03,T03,T04,T04
	.byte T05,T05,T06,T06,T07,T07,$00,$00
CVTUNE02:
	.byte $0D,$0C,$0B,$0A,$09,$08,$07,$06
	.byte $05,$04,$03,$02,$01,$00,$00,$00

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Thu Aug 04, 2016 3:17 am
by PacManPlus
Ok, I think I know what was going on...

If you look at the FamiTracker data,

Code: Select all

PATTERN 00
ROW 00 : ... .. . ... : ... .. . ... : ... .. . ... : 5-# 00 D F01 : ... .. . ...
ROW 01 : ... .. . ... : ... .. . ... : ... .. . ... : 4-# 00 C ... : ... .. . ...
ROW 02 : ... .. . ... : ... .. . ... : ... .. . ... : 3-# 00 B F02 : ... .. . ...
ROW 03 : ... .. . ... : ... .. . ... : ... .. . ... : 2-# 00 A ... : ... .. . ...
ROW 04 : ... .. . ... : ... .. . ... : ... .. . ... : 1-# 00 9 F03 : ... .. . ...
ROW 05 : ... .. . ... : ... .. . ... : ... .. . ... : 0-# 00 8 ... : ... .. . ...
ROW 06 : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 7 F04 : ... .. . ...
ROW 07 : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 6 ... : ... .. . ...
ROW 08 : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 5 F05 : ... .. . ...
ROW 09 : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 4 ... : ... .. . ...
ROW 0A : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 3 F06 : ... .. . ...
ROW 0B : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 2 ... : ... .. . ...
ROW 0C : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 1 F07 : ... .. . ...
ROW 0D : ... .. . ... : ... .. . ... : ... .. . ... : ... .. 0 ... : ... .. . ...
ROW 0E : ... .. . ... : ... .. . ... : ... .. . ... : ... .. . ... : ... .. . ...
ROW 0F : ... .. . ... : ... .. . ... : ... .. . ... : ... .. . ... : ... .. . ...
...the '5, 4, 3, 2, 1' down the left-hand side is actually the inverse of what the data is, for some reason. I had to use $8A,$8B,$8C,$8D,$8E, and $8F. Also, I thought the $00 in the second column was the mode, and I guess it isn't, because I had to use Mode-1 to get that sound (hence the $8X in my listed values above)...
Strange.

So, it looks like the third column is the volume, and the fourth is the number of frames per sound.
At least I have a starting point now.
Bob

Re: Does this exist? (Atari 2600 TIA -> NES 2A03 Note conv.)

Posted: Thu Aug 04, 2016 4:24 am
by thefox
PacManPlus wrote:...the '5, 4, 3, 2, 1' down the left-hand side is actually the inverse of what the data is, for some reason. I had to use $8A,$8B,$8C,$8D,$8E, and $8F. Also, I thought the $00 in the second column was the mode, and I guess it isn't, because I had to use Mode-1 to get that sound (hence the $8X in my listed values above)...
Strange.
Yeah, this is actually not as strange as it sounds. In the APU noise channel, $0 means the lowest period (= highest frequency) and $F is the highest period (lowest frequency). It's reversed in FamiTracker, probably because for most people it would make most sense that "bigger number" should mean "higher frequency".

Simply EOR the value with $F and you're good to go.