weird problem with rdlong
I am having a weird problem with rdlong. It dereferences one pointer correctly but fails on the next one. I think I'm handling both pointers the same, and could use an extra eye or two on the problem.
This is the PASM and the output of a SPIN diagnostic. The left column is diagnostics and the right column is the real code. Ft* are function temps.
On the red boxed line showing the contents of address $6210 (aCycleTraceBufferStart), you can see that ft1 in PASM read address 4B8C, and ft3 correctly got the value $BEEFDEAD at the end of that buffer. Ft3 correctly got the address $4C44, which you can verify two lines above. But when I do "rdlong ft2,ft3", ft2 gets the wrong value! The last value in paragraph $6210 is $01FC, which is incorrect. The correct value is $07F4, as shown in the dump two lines above, and the line above that with the '?' mark. I know the read value is incorrect because the following code does the wrong things, so it's not just an indication error.
Thinking that the variable is changing when I read it, I first made a shadow, which is why there are two identical values at $4C40. At one time, I also had stabilization code in PASM that forced made the code loop until it read the same value twice in a row. The ft* variables are at the end of PASM right before FIT, and there are 5 longs left in the cog.
Can some kind soul point out my error?
Comments
Hi,
Without seeing the actual code it might be difficult to understand what is going on.
This is as much as I can show (edited: replaced indented diagnostic code in ShiftSpinHistory):
ShiftSpinHistory (diagnostic lines removed here) is called when FastGap sees a new sensor edge. It relies on initial setup of pointers to SPIN variables lSlotReaderHistoryOfTag and lTagHistoryAlloc. lTagHistoryAlloc tells what elements of lSlotReaderHistoryOfTag need to be shifted. If "if_z jmp #:ssh_loop_next " is commented, everything gets shifted every time. If it is not commented, the wrong cells get shifted because ft2 is wrong.
This is the SPIN diagnostic:
Just a shot in the dark, but do you have any bytes or words declared above lSlotReaderHistoryOfTag_p and lTagHistoryAlloc_p?
You're passing the address of rx_head through par, then adding offsets to get the pointers to pSlotReaderHistoryOfTag_p and pTagHistoryAlloc_p.
(edited 13Sep21) There are roughly 24 longs before lSlotReaderHistoryOfTag_p, spacing that variable out to address 96. That's the point of the ellipses and the comments '96 and '100. There are no variables of other sizes declared.
The diagnostic screenshot shows that pSlotReaderHistoryOfTag_p ($4B8C) and its dereference ($beefdead at offset $80) are correct, and that the pointer to pTagHistoryAlloc_p ($4C44 in ft3) is correct as well. Only the dereference of the second pointer is bad: "rdlong ft2,ft3" places $0000_01FC in ft2, where the SPIN diagnostic shows that location holding $0000_07F4.
Is there another way to share addresses between SPIN and PASM? All the PASM examples I have seen do it more or less like that.
I should add that ShiftSpinHistory works correctly in that all 32 longs get shifted and the guard value $beefdead at the end is not touched. The point of *pTagHistoryAlloc_p in ft2 would be to shift only the currently allocated array cells, so I can inspect the data later to see status when the resource was consumed. That means an awful lot of things have already come together. It's just "rdlong ft2,ft3" messing up. I'm hoping someone will explain a condition where you can only rdlong so many times in a row or something. Although I added NOPs and they did not help.
Hi Larry,
I have to admit, that I do not understand, what your code is doing. And that I did not invest too much time.
As I never have heard, that rdlong does not work, I would search in other directions. Like silly things, which have happend to silly me.
I would try to go back to a simpler more direct way for debugging. For example load a 9bit constant into a register and wrlong this value to a known fixed destination. And I would try a second set of hardware...
Good luck.
Thanks for trying, Christof.
Hi, I seem to remember, that there was some issue with "FIT" at some time. So does your code reach $1F0 in cog ram?
In the debug screenshot, the last line, commented, is "__testmem res 5". If I uncomment that, compile works. if I change 5 to 6, compile fails. I think that means that the DAT section is 5 longs smaller than $1F0. I moved the FT* variables further up and it did not help.
I commented FIT and it did not help.
This is what It's doing today:
I changed the PASM code to look at an array of ID lengths rather than the old bitmap, which expresses the nonzero lengths in the same array. My code captures several views of the data as it comes in, to save time when reporting (up to 33 times/sec: right now the system is running around half speed to allow time for debug prints). Note the pattern at the end of $6454. That is the result of "rdlong ft2,ft3" written to ft4. It is 4 bytes of $0C in a row. That can happen if my read from $60e8 really read from $60EA (or $60E9 or $60EB). I can't think of other memory in my application that would have that pattern. The book says that the address for rdlong is always rounded for you. The "E8 60 00 00" on line $6454 is the value of FT3, showing the correct address. So what can make rdlong "miss its target"?
Should I replace the propeller 1 chip?
Just a general observation after more than 50 years experience: it's virtually never the hardware.
-Phil
I'll second Phil's observation. Some general things to watch for:
(1) Using "res" is a bit risky, it creates uninitialized variables and is also a trap if you happen to put anything after it. Try changing "res 5" to "long 0[5]", at least until everything is debugged.
(2) On the P1, rdlong expects a long address. If the lower 2 bits of the address are not 0, they'll be forced to 0.
(3) Look carefully in the assembly code for missing "#" (especially on jumps, but sometimes on "mov" and other instructions). Also check all "cmp" instructions to make sure they set the flags. flexspin will help with detecting some of these kinds of bugs, but not all.
there is a Propeller Simulator named GEARS (written in C#) maybe you can try this one to single step your program.
Else I think @Cluso99 wrote a simple debugger for PASM.
sorry, have no links,
Mike
Thanks for all the suggestions, folks. I am going on travel tomorrow morning and will not be able to try anything for a week.
For the record, I never resolved this. Just rewrote the function a different way. If I was doing something stupid, it's lost now. Never did get GEAR to work at this level. Thanks again to the group for trying to help.