Reading the controller?
Moderator: Moderators
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.
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.
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.
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.
Recursiveness can be very useful, although probably not in a NES game.Bregalad wrote:IAlso, it's possible for subroutine to call themselves (this often isn't very usefull)
My point was that "can't ever" is a strong word.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?
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.tokumaru wrote:Recursiveness can be very useful, although probably not in a NES game.
- Laserbeak43
- Posts: 188
- Joined: Fri Sep 21, 2007 4:31 pm
- Contact:
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:
same result.
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
This is enabling square 2 and disabling the other channels. If you want to enable square 1 and 2, write $03 to $4015Laserbeak43 wrote: lda #$02 ; Enable square 2?
sta $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
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.
- Laserbeak43
- Posts: 188
- Joined: Fri Sep 21, 2007 4:31 pm
- Contact:
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.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?
- Laserbeak43
- Posts: 188
- Joined: Fri Sep 21, 2007 4:31 pm
- Contact:
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.Disch wrote:
Here's a quick example:
This should work.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
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.
- Laserbeak43
- Posts: 188
- Joined: Fri Sep 21, 2007 4:31 pm
- Contact:
lol no i wasn't sure how to load values into registers.tepples wrote:To write to a register:
lda #value
sta register address
What kind of "manipulation" do you need help with? Or is the problem just that there is no 6502 tutorial on nesdevwiki yet?
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?
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
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
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:
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
$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:
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.
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:
The high two bits of the value you write to $4000 set the duty.blargg's APU doc wrote: $4000/4 ddle nnnn duty, loop env/disable length, env disable, vol/env
period
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
Yes. Whatever value you set the register to determines what the hardware does.Laserbeak43 wrote:quick question, the number value loaded into the register determines what feature will be used?
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.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?
$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
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.
- Laserbeak43
- Posts: 188
- Joined: Fri Sep 21, 2007 4:31 pm
- Contact:
Difference between using AND and CMP.
I noticed that this:
Does the same thing that this did;
Is the bit of code that uses the mask and beq better, or more efficient? Or are the essentially the same thing?
Thanks,
T
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:
Code: Select all
;Check the state of the right key
lda button_state
and #key_right ;mask
beq right_not_pressed ;branch if equals zero
jsr right_is_pressed
right_not_pressed:
Thanks,
T