PDA

View Full Version : Assembly Doesn't Work Right



Jamesx
02-09-2007, 02:57 AM
I have a simple problem in assembly that is bugging me. Please refer to the program below, which is set up for a Demo Board Basically, I set up a CLK pulse to run really slowly, and flashes an LED. Another part of the program monitors that pin and once it goes high a second LED is flashed on/off. This happens 5 times, the second LED stops flashing, and the program then goes into an infinite loop.

The problem is with the MOV t1, #0 statement at the top of the program. If this statement is included, the counter T22 does not get incremented properly, and the second LED keeps flashing. Only if this statement is commented out does the program work as expected.

Why does it work this way? It shouldn't make any difference whether or not this MOV statement is included or not.

I have tried with an ADD t1, #0 statement, and when an ADD is used instead of a MOV, the program works as expected and stops after 5 times through. What difference would it make if an ADD statement were used instead of a MOV?


For those interested in following along with a Debug mode, there is a 230400 baud output on Pin 6. The code for this is derived from the Fullduplex object.

Thanks for any ideas.

Jim C




CON
_clkmode = xtal1 + pll16x ' use crystal x 16
_xinfreq = 5_000_000 ' external xtal is 5 MHz
PUB start
cognew(@entry,0)
DAT org
entry or dira, PortBits
' mov t22, #0
movi ctra,#%0_00100_000 'set counter mode to NCO single ended
movs ctra,#%00010000 'set APIN to portbit 16: CLK
mov frqa, Freq_ '
or outa, txmask
Main_Loop test CLK, ina wz
if_nz jmp Main_Loop
or outa, LED ' LED on to track progress
mov Time, cnt
add Time, delay ' pause: to after CLK
waitcnt Time, #0
andn outa, LED 'LED off
mov txdata,t22
call #transmit

add t22, #1
cmp t22, #5 wc
if_c jmp #Main_Loop

test_5 nop
jmp #test_5

transmit
or txdata, #$100
shl txdata, #1
mov txbits, #10
mov txcnt, cnt
:bit test txdata, #1 wc ' output bit
muxc outa, txmask
add txcnt, bitticks ' ready next cnt
:wait mov t4, txcnt ' check if bit transmit period done
sub t4, cnt
cmps t4, #0 wc
if_nc jmp #:wait
shr txdata,#1
djnz txbits,#:bit ' another bit to transmit?
transmit_ret ret ' jump to instr. after call instr.

t22 long 0
Delay long 30_000_000
CLK long %00000000_00000001_00000000_00000000
PortBits long %00000000_00000011_00000000_01000000
LED long %00000000_00000010_00000000_00000000
Freq_ long %00000000_00000000_00000000_10000000

bitticks long 348 'for 230400.baud
txmask long %00000000_00000000_00000000_01000000
Time res 1
t4 res 1
txdata res 1
txbits res 1
txcnt res 1

Paul Baker
02-09-2007, 03:31 AM
Isn't this the same problem you were reporting in this thread: http://forums.parallax.com/showthread.php?p=630422

Is there a reason why·you are starting a new thread?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker (mailto:pbaker@parallax.com)
Propeller Applications Engineer
[/url][url=http://www.parallax.com] (http://www.parallax.com)
Parallax, Inc. (http://www.parallax.com)

Post Edited (Paul Baker (Parallax)) : 2/8/2007 8:45:33 PM GMT

Jamesx
02-09-2007, 04:52 AM
Same problem. Same obsession. Sorry for the second thread. Can we remove the first one?

Jim C

cgracey
02-09-2007, 05:47 AM
The problem is that you forgot to put a # on the 'if_nz jmp {#}Main_Loop', which was causing it to jump to the contents of the Main_Loop location's lower 9 bits, not·to Main_Loop. So, it was jumping to INA ($1F2), which would read an instruction like a D (not an S) register,·causing a·$0000_0000, or NOP, to execute. It was then executing NOP's all the way $1FF,·at which point·it wrapped around to $000 and executed your program from the beginning, hitting that 'mov t22,#0' at $001 again. Forgetting the # on a jmp can cause crazy things to happen.


Jamesx said...



CON
_clkmode = xtal1 + pll16x ' use crystal x 16
_xinfreq = 5_000_000 ' external xtal is 5 MHz
PUB start
cognew(@entry,0)
DAT org
entry or dira, PortBits
' mov t22, #0
movi ctra,#%0_00100_000 'set counter mode to NCO single ended
movs ctra,#%00010000 'set APIN to portbit 16: CLK
mov frqa, Freq_ '
or outa, txmask
Main_Loop test CLK, ina wz
if_nz jmp Main_Loop
or outa, LED ' LED on to track progress
mov Time, cnt
add Time, delay ' pause: to after CLK
waitcnt Time, #0
andn outa, LED 'LED off
mov txdata,t22
call #transmit

add t22, #1
cmp t22, #5 wc
if_c jmp #Main_Loop

test_5 nop
jmp #test_5

transmit
or txdata, #$100
shl txdata, #1
mov txbits, #10
mov txcnt, cnt
:bit test txdata, #1 wc ' output bit
muxc outa, txmask
add txcnt, bitticks ' ready next cnt
:wait mov t4, txcnt ' check if bit transmit period done
sub t4, cnt
cmps t4, #0 wc
if_nc jmp #:wait
shr txdata,#1
djnz txbits,#:bit ' another bit to transmit?
transmit_ret ret ' jump to instr. after call instr.

t22 long 0
Delay long 30_000_000
CLK long %00000000_00000001_00000000_00000000
PortBits long %00000000_00000011_00000000_01000000
LED long %00000000_00000010_00000000_00000000
Freq_ long %00000000_00000000_00000000_10000000

bitticks long 348 'for 230400.baud
txmask long %00000000_00000000_00000000_01000000
Time res 1
t4 res 1
txdata res 1
txbits res 1
txcnt res 1





▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


Chip Gracey
Parallax, Inc.

Jamesx
02-09-2007, 08:43 AM
Chip:

Thanks for the explanation of my simple error. I figured it was going to be obvious once it was pointed out: I just couldn't see the tree for the forest.

This also explains why it worked correctly with an ADD #0 instead of the MOV #0. Returning to the ADD instruction, while incorrect as the flow was intended, didn't alter the incremented variable. But, returning to the MOV #0 each time zero'ed out the variable each time. Duh!

Jim C