CALLB #\A Syntax Question
Bob Drury
Posts: 236
in Propeller 2
Curious about setting register PTRB? CogInit has PTRA as a pointer that can be set when calling PASM program. What about PTRB? Is this just set within a PASM program? The atached code seems to work by
setting PTRB in the program, but if I remove MOV PTRB,##PTRB_Stack statement it stills works. I think
the reason it still works is PTRB = 0 and the stack is pointing to Hub Ram =0 which would mean
the Spin2 code is overwritten and since there is no spin2 code it doesn't matter.
Comments on how to best set PTRB would be apreciated.
Regards
Bob (WRD)
CON {Processor Timing} _clkfreq = 200_000_000 'processor clock speed VAR Byte cogStarted_COGEXEC_NEW 'cog ID started is returned or -1 if not started OBJ PUB main() cogStarted_COGEXEC_NEW := COGINIT(COGEXEC_NEW,@CallProgram,$FFFF_FFFF) repeat 'keep cog 0 running DAT ORGH 'Assign stack in Hub Ram PTRB_Stack long 8 DAT ORG 0 'COGINIT(COGEXEC_NEW,@CallProgram,$FFFF_FFFF) CallProgram NOP MOV PTRB,##PTRB_Stack CALLB #Subroutine 'Compiler takes Subroutine-Call Program and generates offset debug("Returned from Subroutine") debug(udec(POPBNum01),udec(POPBNum02),udec(POPBNum03)) debug(udec(POPBNum04),udec(POPBNum05),udec(POPBNum06),udec(POPBNum07)) Loop1 NOP JMP #LooP1 Subroutine NOP debug("Now In Subroutine") WAITX clkTicks debug("PUSHB Num01 to Num07") PUSHB Num01 PUSHB Num02 PUSHB Num03 PUSHB Num04 PUSHB Num05 PUSHB Num06 PUSHB Num07 WAITX clkTicks debug("POPB POPBNum07 to POPBNum01") POPB POPBNum07 POPB POPbNum06 POPB POPBNum05 POPB POPBNum04 POPB POPBNum03 POPB POPBNum02 POPB POPBNum01 RETB Loop2 NOP JMP #Loop2 clkTicks long $00A00_0000 Num01 long 1 Num02 long 2 Num03 long 3 Num04 long 4 Num05 long 5 Num06 long 6 Num07 long 7 POPBNum01 long 0 POPBNum02 long 0 POPBNum03 long 0 POPBNum04 long 0 POPBNum05 long 0 POPBNum06 long 0 POPBNum07 long 0
Comments
Bob,
PTRB** can** be used like any other cogram long, but given that it is loaded with the program address on COGINIT, and all of the pointer related machinery associated with it, it makes most sense to use it as a hubram pointer.
I wouldn't be surprised to find that cog0 is affected. If you were to setup a pair of instructions to toggle a pin (for a pin with an LED attached) and wait (e.g. 100ms), in the SPIN2 repeat clause, you might see whether the SPIN2 code in cog0 is corrupted.
Edit: With an empty repeat loop the SPIN2 interpreter may not fetch anything from hubram. I wouldn't expect you to be able to restart cog0 and get the same results after running this code.
Also note, that unlike the Propeller 1, you don't actually need a SPIN2 stub to start off a PASM2 program. As the SPIN2 interpreter isn't held in ROM, it becomes just like any other PASM2 program.
That would be correct. Not advised though, there is a couple of system variables stashed in that general area. Err, rather, the stack will begin to overwrite the hubRAM copy of your program. I forgot, COGINIT loads PTRB with address of your program in hubRAM.
Thanks for reply. I believe what you are saying is that PTRB somehow when cogStarted_COGEXEC_NEW := COGINIT(COGEXEC_NEW,@CallProgram,$FFFF_FFFF) is executed
PTRB is loaded with @CallProgram address and PTRA is loaded with $FFFF_FFFF. I have not seen anything to suggest this other than a cryptic message says " PTRB code pointer passed from COGINIT". I started a new chat on this and AJl has some info.
1) Do you know where in the literature this is documented?
2) What is the concept behind loading PTRB with the Subroutine start address? (@CallProgram in the above code)
Regards and Thanks (Boy I am learning how little I know)
Bob (WRD)
1) Probably in the spin2 document under coginit
2) So you know where the loaded code resides - use is up to the programmer
PTRA is also loaded in pasm if the immediate instruction before cogstart is a SETQ ##somePTRAvalue
If the COGINIT is preceded by a SETQ it will set PTRA to the value specified by the SETQ.
These are hardwired in the COGINIT instruction, not a Spin feature. Documented in the instruction spreadsheet - https://docs.google.com/spreadsheets/d/1_vJk-Ad569UMwgXTKTdfJkHYHpc1rZwxB-DcIiAZNdk/edit?usp=sharing
I see in the instruction sheet " COGINIT {#}D,{#}S {WC} Start cog selected by D. S[19:0] sets hub startup address and PTRB of cog. Prior SETQ sets PTRA of cog."
So "sets hub start up address" must pass control from hub spin to PASM program and "sets hub startup address and PTRB of cog" is interpreted as sets PTRB the same address
as the start up address (@CallProgram in the above code). Definitely will add this to Coginit spin description. This information COGINIT {#}D,{#}S is for PASM but apparently applies to the spin2 command.(a little cryptic) Please let me know if going down the right track.
Regards and Thanks
Bob (WRD)
Yep, that instruction is the only way to start/restart a cog. So it's going to dictate to a degree.
Also, the Spin COGINIT() function is intended for starting a pasm task in a fresh cog. So it's really a Pasm environment, just launched from Spin. COGSPIN() is function for starting a fresh cog with spin task.
Also, as noted in the other thread
From the COGINIT section of the 'Parallax Propeller 2 Documentation':
S/# = address This value is either the hub address from which the target cog will
load from, or it is the cog/hub address from which the target cog
will begin executing at, depending on D[5]. This 32-bit value will be
written into the target cog's PTRB register.