PDA

View Full Version : running ctra nco, adding to phsa to get pwm like behavior



IncVoid
12-25-2009, 05:22 PM
I'm trying to test phsa's msb to know what part of the outputted square wave i'm at.
If i'm in the low phase, I want to do an add, store that I did the add in a flag, so I don't add a second time(until next cycle).
Then when phsa is in the high phase of it's outputted square wave, do a 0 add to phsa. store that I added(resetting the lowphase add flag)

the adder flag basically waits for phsa's msb to catch up, so we can add to phsa, and toggle my adder flag.

the values added are opposite. depending on if I want longer off to on time, or on to off time. so I do one add of a value, and one 0 value add.
trying to get cut the off or on phase by 31/32 so I'm adding 7c00_0000.

so it's mostly on..or mostly off with. I don't think the code is taking too long. I'm running
_CLKMODE = XTAL1 + PLL8X
_XINFREQ = 8_000_000
which I believe is 40mhz?
Think my frqa value was 256d, but I cut it down to 33/64ths or what it was before cause the cycle length shortened due to the add if my math is right.
I think actual FRQA value is 132d. this gets added once per clock. I believe 4 clocks per instruction? so every instruction I'm getting 528 added?

before to get it less off. I'd CMP phsa with a value and MOV PHSA, #0 if it was over my limit.

I was thinking either my code is doing to much for the "window" that my add has to take place in and not overlap into the next phase.
$8400_0000 (half 2^32 + 1/32 of 2^32, the cut half) is my desired phsa "length."
$8400_0000/132 = $100_0000
$100_0000/4clocks per instruction = $40_0000 instructions per cycle? but my window is really only1/33 of this cycle? so my code has to check twice in this window so the add could take place at the beginning or end of this window.

$40_0000/33 = 127,100 127k instructions, I'm almost posative my loop to get the buttons on the dpad, check what part of phsa i'm at, and set trigger out. is less than 127k instructions even if I checked phsa to do the adds every time I shifted a bit from the 4021 parallel to serial shift chip, that is 127k instructions/8bit to shift = 15k instructions.
I can't even fit that many instructions in. I'm posative it isn't slow enough.

http://i47.tinypic.com/2me4as3.jpg
That is what I'm trying to do. Make the sawtooth wave that represents phsa to jump up by an add.

The only thing I can think of is that "test phsa, _phsa_half_bit wz" doesn't like phsa as a register?

before I'd do a "cmp phsa, _phsa_high_cap wz wc" seemed to work..why aren't my tests and adds?




test _nes_bits, _TRIGGER_BUTTON wc
if_nc xor _pressed, _pressed 'if button isn't pressed 0 out _pressed
if_nc jmp #dira_set
test _pressed, _pressed2 wz 'if pressed is 0 set 0 flag

if_nz jmp #adder_code 'no new press jump to adder.

newpress mov _pressed, _pressed2 'if pressed was 0 and trigger is down
mov phsa, _phsa_high_bit 'reset phsa
mov _bottom_flag, #0

adder_code test phsa, _phsa_half_bit wz 'test if bit 31 is set
if_nz jmp #off_adder 'ifnot bottom half, go to top adder
test _bottom_flag, #%00000_0001 wz 'did we add before?
if_z add phsa, _on_add_15 'if not add to phsa
mov _bottom_flag,#%00000_0001 'store that we added so we don't add next time
jmp #dira_set 'jmp to setting the trigger pin as output

off_adder test _bottom_flag, #%00000_0001 wz 'check bottom flag to see if we have added before
mov _bottom_flag, #0
'if_z jmp #dira_set 'if we've done our add before, leave
'add phsa, _off_add 'if not... do our top phase add
'mov _bottom_flag, #0 'set flag to signal next add shoudl be on top or bottom

dira_set test _nes_bits, _TRIGGER_BUTTON wc 'set our trigger out if its pressed.
if_c or DIRA, _SET_TRIGGER
if_nc and DIRA, _CLEAR_TRIGGER

' continue looping...
jmp #NES_Latchbits

kuroneko
12-25-2009, 06:10 PM
IncVoid said...
The only thing I can think of is that 'test phsa, _phsa_half_bit wz' doesn't like phsa as a register?

before I'd do a 'cmp phsa, _phsa_high_cap wz wc' seemed to work..why aren't my tests and adds?
With the exception of mov phsx, ??? - which loads shadow location and accumulator - any instruction with phsx in its destination slot works on the shadow register only1, which is not what you want. To modify the counter register you have to move it into a normal r/w register first, do the modification then move it back.

<sup>1 Edit: While said operations work on the shadow register, the result is still written to both, shadow register and accumulator.

Post Edited (kuroneko) : 12/28/2009 12:57:54 AM GMT

IncVoid
12-28-2009, 03:56 AM
So that is why my add isn't working, I'm adding to shadow register(don't understand that role all to well yet), which isn't "sticking" to the accumulator part of phsa register?
Would my tests still work off of the shadow register?
The shadow register just takes my add and discards it. Only copies whats in phsa to it?
I'll try to do a mov add and move back this time and see what happens. Thanks! I though it was the test inst that wasn't working right.
Thanks for the fast response too!

kuroneko
12-28-2009, 07:53 AM
IncVoid said...
So that is why my add isn't working, I'm adding to shadow register(don't understand that role all to well yet), which isn't "sticking" to the accumulator part of phsa register?

For simplicity the cog RAM holds 512 registers (RAM cells), the last 16 are overloaded with special registers and depending on how you work with them you either get the special bits or the underlying cog RAM. There isn't a special role attached to them (they can come in handy if you need an extra 16 longs for storage and/or code).


IncVoid said...
Would my tests still work off of the shadow register?
The shadow register just takes my add and discards it. Only copies whats in phsa to it?

test is just an and instruction without the result written. So if you use phsx in the destination slot then you work/test on the shadow register. As for add - I just re-checked on real h/w - the operation is performed on the shadow register, but the result is written to both shadow register and accumulator. So if you want the op to be based on the accumulator, you have to fetch its value first.

For example, lets say you initialised phsx with 42 and the counter is in logic:always mode (frqx = 1). Then you wait a bit, run some other code. Now the shadow register still holds 42 while the accumulator is slightly advanced. Performing an add phsx, #1 will increment the shadow register but also reset the accumulator to 43.

Post Edited (kuroneko) : 12/28/2009 1:13:48 AM GMT