Strange problem with CALL indirect
Peter Jakacki
Posts: 10,193
I have tracked down a problem with CALL REG where REG holds the address of a routine normally in the hub. Typically I will have task vectors that are normally zero for default but if I want them to do something different I load them up with the address of the routine I need it to be. But it just won't work and I checked the binary to make sure it was assembled correctly and it is. $FD63.302D where D is $198 so everything looks correct but it doesn't work. So I changed the setup so that it ended up doing a JMP REG instead and that works.
So this code is running in the hub but I will check its behaviour in cog as well and report back but this is mainly a heads-up for Chip to double check.
So this code is running in the hub but I will check its behaviour in cog as well and report back but this is mainly a heads-up for Chip to double check.
' Inline vector check and exeute - usage: QJMP,keypoll ' QJMP rdword X,PTRA++ ' read register address inline add X,regptr ' add in task register offset rdword X,X wz ' read contents of vector if_z ret ' and ignore it if zero call #EXIT jmp X { this doesn't work call X ' execute vector jmp #EXIT ' terminate rather than continue }
Comments
* COG CALL # -> COG
* COG CALL D -> COG
* COG CALL # -> HUB
* COG CALL D -> HUB
* HUB CALL # -> HUB
* HUB CALL D -> HUB
* HUB CALL # -> COG
* HUB CALL D -> COG
All passed. I also tried the above tests with varying number of items in the stack, including a full stack.
In your comments above, are you saying that the JMP works, as shown in the above code (i.e. preceded by a "call #EXIT")?
Thanks for testing out all those variations and I know I must get down to the bottom of the problem and whether it might be a hardware stack problem as I haven't tried deliberately calling more than 8 levels deep. I don't think I'm that deep but I will have to check. Definitely though the code I used wouldn't work until I used the JMP and before then I even include some diagnostics to make sure it was executing the call instruction which it was but I don't know where it went to and it didn't crash either. The vector was correct and I could manually "call" it and the routine worked.
Incidentally, here's the test that I ran.
https://github.com/Seairth/P2UnitTests/blob/master/test_call.spin
When I tested the filled and partially-filled stack, I just inserted varying numbers of PUSH instructions at the top...
Oh yeah! I'll add them the next chance I get.
So you can't use CALL/RET to jump in and out of LUT exec mode?
You can!
There just aren't any CALL/RET instructions that use the LUT as a stack.
Oh. Yeah, I wasn't expecting that anyhow. The tests just cover mode switches.