Page 3 of 4
Posted: Tue Feb 26, 2008 9:03 am
In fact any code that when executed takes two "RTS" in a chain is unoptimized.
Also, it's possible for subroutine to call themselves (this often isn't very usefull), or to call the latest part of themselves before they return, and this can proof usefull if the end should be done a couple of times instead of just one, this can make a shorter loop.

Posted: Tue Feb 26, 2008 9:19 am
OK, let's explain all the tiny assembly tricks to the newbies and confuse the hell out of them from the start, shall we?

I'd rather present the usual way of doing things to people who are just starting, and eventually they'll learn these tricks by themselves. Of course there are several ways to call a routine, but as long as a beginner sticks to JSR, they should be safe.
Bregalad wrote:IAlso, it's possible for subroutine to call themselves (this often isn't very usefull)
Recursiveness can be very useful, although probably not in a NES game.

Posted: Tue Feb 26, 2008 5:19 pm
tokumaru wrote:OK, let's explain all the tiny assembly tricks to the newbies and confuse the hell out of them from the start, shall we?
My point was that "can't ever" is a strong word.
tokumaru wrote:Recursiveness can be very useful, although probably not in a NES game.
Flood fill is commonly implemented as a recursive algorithm, and I can think of a few places where flood fill would be useful, but I'll leave those alone for now.

Posted: Tue Mar 04, 2008 12:06 pm
well, i've gotten the code to work, long ever since. but i'm experiencing delays(latency) between button presses and short envelope times. i was wondering if the line "lda #\$9F" was just a short envelope time, so under it i tried lda FF in what i thought was square 2:

Code: Select all

``````right_is_pressed: ; play sound when right arrow is pressed.

lda #\$01   ; Enable square 1
sta \$4015  ; this register gets written to first to enable sound channel. Then come the other registers
lda  #\$02  ; Enable square 2?
sta \$4015
lda #\$9F   ; Envelope
sta \$4000
lda #\$FF
sta \$4004
lda #\$21   ; Start tone
sta \$4003
lda #\$FF
sta \$4007
rts
``````
same result.

Posted: Tue Mar 04, 2008 1:10 pm
Laserbeak43 wrote: lda #\$02 ; Enable square 2?
sta \$4015
This is enabling square 2 and disabling the other channels. If you want to enable square 1 and 2, write \$03 to \$4015

Or... what I'd recommend is just write \$0F once to \$4015 at startup to enable everything (note that no channels will play any sound until prompted to do so, even if you do this), then you can forget all about \$4015 completely (unless you want to use the DMC)

Anyway I don't see what could be causing latency. What might be causing a problem though, is the sweep unit. Even if you disable sweep, it can still silence low notes unless you switch it to 'negative' mode.

Here's a quick example:

Code: Select all

``````lda #%10011000   ; 50% duty, decay disabled, volume=8
sta \$4000

lda #%00001000  ; disable sweep, set it to negative mode
sta \$4001

lda #\$FD   ; period = \$FD -- concert A (440 Hz)
sta \$4002

lda #%01010000 ; high bits of period=0, set length to play for half a second
sta \$4003
``````
This should work.

How I usually approach problems like this is I look at a technical doc covering the register descriptions... then just write to every register setting everything to a specific value.

If by "short envelope time" you meant the note was cutting out early, that likely was the length counter. Both %00100xxx (\$21) and %11111xxx (\$FF) -- the values you were writing to the length counter reg -- are both short values. %00001xxx (\$08) is the longest you can set the length counter to. Or, you could disable the length counter via \$4000.5 to have it play indefinately.

Posted: Tue Mar 04, 2008 3:03 pm
I bet the latency is because the sound is effectively starting when you release the button. To test this hypothesis, try holding the button for a while before releasing it. Does the sound begin when you press or release it?

Posted: Wed Mar 05, 2008 6:47 am
blargg wrote:I bet the latency is because the sound is effectively starting when you release the button. To test this hypothesis, try holding the button for a while before releasing it. Does the sound begin when you press or release it?
i hold down the right button for 5 seconds or more, release it and nothing happens. i press the left key rapidly and stop, and it after i let go, it beeps a few times.

Posted: Wed Mar 05, 2008 7:00 am
Disch wrote:

Here's a quick example:

Code: Select all

``````lda #%10011000   ; 50% duty, decay disabled, volume=8
sta \$4000

lda #%00001000  ; disable sweep, set it to negative mode
sta \$4001

lda #\$FD   ; period = \$FD -- concert A (440 Hz)
sta \$4002

lda #%01010000 ; high bits of period=0, set length to play for half a second
sta \$4003
``````
This should work.

How I usually approach problems like this is I look at a technical doc covering the register descriptions... then just write to every register setting everything to a specific value.

If by "short envelope time" you meant the note was cutting out early, that likely was the length counter. Both %00100xxx (\$21) and %11111xxx (\$FF) -- the values you were writing to the length counter reg -- are both short values. %00001xxx (\$08) is the longest you can set the length counter to. Or, you could disable the length counter via \$4000.5 to have it play indefinately.
the docs just leave me lost. i must read most of both blargg's and brad's yesterday. but i'm still confused on how to program them. I mean. the docs tell you registers need to be manipulated. but not the syntax needed to do that. and i haven't read a tutorial that has made that very clear either. to the point that i could look at the reference then look at a tutorial and learn how to write to that register.

Posted: Wed Mar 05, 2008 7:21 am
To write to a register:

lda #value

What kind of "manipulation" do you need help with? Or is the problem just that there is no 6502 tutorial on nesdevwiki yet?

Posted: Wed Mar 05, 2008 7:38 am
tepples wrote:To write to a register:

lda #value

What kind of "manipulation" do you need help with? Or is the problem just that there is no 6502 tutorial on nesdevwiki yet?
lol no i wasn't sure how to load values into registers.

quick question, the number value loaded into the register determines what feature will be used?

so if #\$01 loads a black hole
and #\$03 loads my ninja turtles dvd
will:
lda #\$03
sta #\$4014
load my ninja turtle DVDs while running a black hole?

Posted: Wed Mar 05, 2008 8:03 am
I hear what you're saying. Not how to load numbers in the sound registers, but which numbers. And then what effect would those numbers have on each sound register.

I have been wondering that too. It would be great to have a list of the effects that can be produced with each useful binary number on each sound register.

T

Posted: Wed Mar 05, 2008 9:08 am
I share the same confusion tepples does. There's no manipulation here other than writing values (writing = STA, STX or STYing).

The bits in the value you write set (or clear) the specific bits of those registers. The bits of those registers control what the system is doing -- so in effect, the value you write determines the behavior of the hardware.

Example:
blargg's APU doc wrote: \$4000/4 ddle nnnn duty, loop env/disable length, env disable, vol/env
period
The high two bits of the value you write to \$4000 set the duty.

Bit 5, when set, will disable the length counter and set the envelope unit to looop. When clear, it will enable length, and the envelope won't loop.

Bit 4 disables (when set) or enables (when clear) the envelope generator

and the low 4 bits set the fixed volume and envelope speed.

So if you want:
- 50% duty (%10xxxxxx)
- disabled length (%xx1xxxxx)
- disabled envelope (%xxx1xxxx)
- a volume level of 8 (%xxxx1000)

then you write %10111000 to \$4000:

LDA #%10111000
STA \$4000
Laserbeak43 wrote:quick question, the number value loaded into the register determines what feature will be used?
Yes. Whatever value you set the register to determines what the hardware does.
so if #\$01 loads a black hole
and #\$03 loads my ninja turtles dvd
will:
lda #\$03
sta #\$4014
load my ninja turtle DVDs while running a black hole?
This example doesn't make any sense. #\$01 doesn't "load" anything, it's just a number. When you write that number to a register, the effect it has depends on what the register does.

\$4014 is kind of tricky, because it's not really an actual register -- it's more like a CPU macro. I don't understand your whole ninja turtle/black hole metaphore but basically \$4014 works like this:

low level:
writing to \$4014 starts a DMA transfer. Bytes are read from \$nn00 (where 'nn' is the value written to \$4014) and written to \$2004 (which puts that byte in OAM). So for example, if do:

LDA #\$03
STA \$4014

that is basically the same thing as:

Code: Select all

``````LDA \$0300
STA \$2004
LDA \$0301
STA \$2004
LDA \$0302
STA \$2004
...
LDA \$03FF
STA \$2004
``````
Only much faster because the CPU doesn't have to fetch opcode and address bytes repeatedly. Plus it's much smaller code.

high level:

Writing to \$4014 copies a 256 byte page to OAM. So if you write \$03 to \$4014, then the page at \$0300-03FF gets copied in full to OAM.

Posted: Sat Mar 29, 2008 2:23 pm
this post has been in the back of my head since your reply. i'm gonna get to it over the weekend hopefuly, thanks.

Posted: Tue Apr 08, 2008 11:44 am
Difference between using AND and CMP.

I noticed that this:

Code: Select all

``````;Check the state of the right key
lda button_state
cmp #key_right           ; compare
bne right_not_pressed  ; branch if not equal to zero
jsr right_is_pressed

right_not_pressed:

``````
Does the same thing that this did;

Code: Select all

``````;Check the state of the right key
lda button_state