ASM Help: SUB Function doing something funny?
Steel
Posts: 313
I am currently working on a Serial Port communications link at 115200 baud.
I am transferring 4 bytes of data (which works great with a 32 bit register)
My plan was to shift the data bits out of my OUTA pin.·
My code successfully works with sending out 1 Byte.· I tried to add a loop to run the code 4 times, and I am having problems with "SUB".· I have assigned a variable "Bytes_Remaining" to The number 4.· Near the end of the code, in "Idle_Line", I subtract 1 from "Bytes_Remaining".· I then compare that to zero, and write the Zero flag if they are equal.· If there are no more bytes remaining then the code goes on...if there are bytes remaining, then it goes back and sends those bytes.
The only problem is that It sends data forever...When I run this code without the "SUB" line in it, it works as expected (The 'Z' flag is not set in the CMP, and it loops infinitely).· But, when I add the "SUB" line, I should expect it to only loop 4 times, right?· It's not..it is running infinitely as well.
Is there something I am missing?
Thanks
SHaun
CON
· _CLKMODE = XTAL1 + PLL16X
· _CLKFREQ = 5_000_000
VAR
··
PUB TOGGLE_MAIN
· DATA:= $AA_A0_55_FF
·
· COGNEW(@INITIALIZE,0)
DAT
······· ORG·· 0
·······
INITIALIZE
······· MOVI·· DIRA, #%010000000
······· MOVI·· OUTA, #%010000000
······· ROR··· DATA, #1·· ' ROlls data value so LSB is on Pin31 on OUTA.· Now·roll the data·
································ 'once more in code to put it on that pin...
······· MOV··· BYTE_REMAINING, #4
·····
START_BIT
······· MOV·· OUTA, #$00······· 'Drop Level to 0
······· CALL #BIT_PAUSE
·············
DATA_BYTE
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 0
······· CALL #BIT_PAUSE
··········
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 1
······· CALL #BIT_PAUSE
··········
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 2
······· CALL #BIT_PAUSE···
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 3
······· CALL #BIT_PAUSE···
······· ROR·· DATA, #1
········ MOV·· OUTA, DATA······· 'BIT 4
······· CALL #BIT_PAUSE···
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 5
······· CALL #BIT_PAUSE···
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 6
······· CALL #BIT_PAUSE···
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 7
······· CALL #BIT_PAUSE···
PARITY_BIT
······· MOVI OUTA, #%010000000·····
······· CALL #BIT_PAUSE
·········
·STOP_BIT
······· 'Don't need to· Change state because it is correct from Parity_Bit.
······· CALL #BIT_PAUSE···
IDLE_LINE··· 'This returns the line back to Idle.
·······
······· MOV·· TIME, CNT
······· ADD·· TIME, PAUSE
······· WAITCNT TIME, PAUSE
······· SUB·· BYTE_REMAINING, #1
······· CMP·· 0, BYTE_REMAINING· WZ
· IF_NZ JMP·· #START_BIT
·······
·······
·····
BIT_PAUSE
······· MOV·· TIME, CNT
······· ADD·· TIME, BIT_TIME
······· WAITCNT TIME, BIT_TIME
BIT_PAUSE_RET
······· RET···
·······
·······
PAUSE········ long··········· 40_000
BIT_TIME····· long··········· 650
DATA········· long··········· 0·· 'This value is brought in from SPIN
BYTE_REMAINING Res············ 1
Time·········· res············ 1
·
·······
Post Edited (Steel) : 7/12/2007 6:19:30 PM GMT
I am transferring 4 bytes of data (which works great with a 32 bit register)
My plan was to shift the data bits out of my OUTA pin.·
My code successfully works with sending out 1 Byte.· I tried to add a loop to run the code 4 times, and I am having problems with "SUB".· I have assigned a variable "Bytes_Remaining" to The number 4.· Near the end of the code, in "Idle_Line", I subtract 1 from "Bytes_Remaining".· I then compare that to zero, and write the Zero flag if they are equal.· If there are no more bytes remaining then the code goes on...if there are bytes remaining, then it goes back and sends those bytes.
The only problem is that It sends data forever...When I run this code without the "SUB" line in it, it works as expected (The 'Z' flag is not set in the CMP, and it loops infinitely).· But, when I add the "SUB" line, I should expect it to only loop 4 times, right?· It's not..it is running infinitely as well.
Is there something I am missing?
Thanks
SHaun
CON
· _CLKMODE = XTAL1 + PLL16X
· _CLKFREQ = 5_000_000
VAR
··
PUB TOGGLE_MAIN
· DATA:= $AA_A0_55_FF
·
· COGNEW(@INITIALIZE,0)
DAT
······· ORG·· 0
·······
INITIALIZE
······· MOVI·· DIRA, #%010000000
······· MOVI·· OUTA, #%010000000
······· ROR··· DATA, #1·· ' ROlls data value so LSB is on Pin31 on OUTA.· Now·roll the data·
································ 'once more in code to put it on that pin...
······· MOV··· BYTE_REMAINING, #4
·····
START_BIT
······· MOV·· OUTA, #$00······· 'Drop Level to 0
······· CALL #BIT_PAUSE
·············
DATA_BYTE
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 0
······· CALL #BIT_PAUSE
··········
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 1
······· CALL #BIT_PAUSE
··········
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 2
······· CALL #BIT_PAUSE···
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 3
······· CALL #BIT_PAUSE···
······· ROR·· DATA, #1
········ MOV·· OUTA, DATA······· 'BIT 4
······· CALL #BIT_PAUSE···
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 5
······· CALL #BIT_PAUSE···
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 6
······· CALL #BIT_PAUSE···
······· ROR·· DATA, #1
······· MOV·· OUTA, DATA········ 'BIT 7
······· CALL #BIT_PAUSE···
PARITY_BIT
······· MOVI OUTA, #%010000000·····
······· CALL #BIT_PAUSE
·········
·STOP_BIT
······· 'Don't need to· Change state because it is correct from Parity_Bit.
······· CALL #BIT_PAUSE···
IDLE_LINE··· 'This returns the line back to Idle.
·······
······· MOV·· TIME, CNT
······· ADD·· TIME, PAUSE
······· WAITCNT TIME, PAUSE
······· SUB·· BYTE_REMAINING, #1
······· CMP·· 0, BYTE_REMAINING· WZ
· IF_NZ JMP·· #START_BIT
·······
·······
·····
BIT_PAUSE
······· MOV·· TIME, CNT
······· ADD·· TIME, BIT_TIME
······· WAITCNT TIME, BIT_TIME
BIT_PAUSE_RET
······· RET···
·······
·······
PAUSE········ long··········· 40_000
BIT_TIME····· long··········· 650
DATA········· long··········· 0·· 'This value is brought in from SPIN
BYTE_REMAINING Res············ 1
Time·········· res············ 1
·
·······
Post Edited (Steel) : 7/12/2007 6:19:30 PM GMT
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Post Edited (Paul Baker (Parallax)) : 7/12/2007 6:49:33 PM GMT
Unfortunately, it is still looping infinitely.
I removed the CMP instruction, and even replaced the SUB instruction with this:
SUB BYTE_REMAINING, #1 WZ, WC
IF_NC_OR_NZ JMP #START_BIT
And it is still an infinite loop...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
2 - 1 =·1······· 0· 0·· 1·· 1···· 1
1 - 1 = 0······· 1· 0·· 0·· 1···· 1
0 - 1 =·..ff···· 0· 1·· 1·· 0···· 1
..ff·- 1 = ..fe· 0· 0·· 1·· 1···· 1
I am using it now, and it works.
Thank you guys