Using SETQ or SETQ2 with Q[9]=1 would seem to be the sensible way to enable CZ writing in XBYTE. This is a bit of a dummy's question: if the D in SETQ/SETQ2 is 9-bit immediate, are the top 23 bits written to Q all zero, ensuring that XBYTE will not modify CZ?
Something not mentioned so far regarding skipping, I think, is that an interrupt routine could change the skip patterns deliberately by executing SKIPF, for example in response to external events. In theory a skip sequence could be extended ad infinitum but probably not beyond.
There are currently two SKIP/SKIPF situations in which interrupts are delayed:
1) On the SKIP/SKIPF instruction, itself.
2) When the <next> instruction is getting cancelled.
#2 was just added yesterday to make things work in cases where the first skip bit is 1. I may now be able to get rid of #1. I will try that today.
I just spent the last day and a half hunting down a bug involving SKIPF/EXECF/BYTEX and interrupts. The solution was to inhibit skip advancement, rather than delaying interrupts, when the interrupt circuit wants to insert its CALLD into the pipeline. This should make single-stepping more sensible.
I will post a new Prop123-A9 image later today.
Ozpropdev, if you could try it out, that would be great.
Chip
The "dummy" step that appeared in the previous SKIPF tests is now fixed.
What has remained the same is the first instruction after a SKIP{F} is executed but stepped over.
The included test runs a SKIP and SKIPF code snippet in COG, HUB and LUT exec modes.
All actions operate as expected except for the initial first step.
Code outputs @115200 baud and press "*" to step through code.
I don't think it's possible to improve it. The reason is that in the SKIPF instruction cycle, we must both cancel the next instruction and advance the PC by some variable amount. After that, we just advance the PC variably.
What I have now looks prettiest for single-stepping, but has caused a critical path that I hope to resolve. If I can't resolve it, we will go back to the way it was just before, where it always pauses on the instruction after SKIPF.
What I have now looks prettiest for single-stepping, but has caused a critical path that I hope to resolve. If I can't resolve it, we will go back to the way it was just before, where it always pauses on the instruction after SKIPF.
As long as the behaviour is predictable, and actually executes correctly, the Debug could fix-up any 1-opcode offsets that result from 'too many balls in the air' ?
Once you have the complex stuff nailed, and have Spin2 done, for a more lightweight diversion you could try PBASIC bytecodes thru the SKIPF engine ?
That gives another (simple) language test point, and you can benchmark P2 vs the venerable Stamps.
We certainly don't want critical path issues.
As JMG pointed out, as long as the behaviour is predictable and documented we can make our debuggers adjust accordingly.
Sorry it's been such a headache.
...Once you have the complex stuff nailed, and have Spin2 done, for a more lightweight diversion you could try PBASIC bytecodes thru the SKIPF engine ?
That gives another (simple) language test point, and you can benchmark P2 vs the venerable Stamps.
And could shut up all the questions about the next stamp?
I really like it. And @Chip is the only one who understands the PBASIC interpreter. Not sure how the language needs to change to accommodate the way bigger Memory, speed and multicore, but even running PBASIC on a P2 would be fantastic.
And would be a nice way to use smaller P2-Family Variants...
Do we have a current functionality / how to in the docs?
Looks like I've got something I want to try. Have followed thos, but did not write code.
Also, I'm unclear on interrupts. Where do things stand there? Does XBYTE come first, interrupts first, or first come, first serve?
XBYTE could be considered a "virtual instruction" that executes when a RET to $1F8..$1FF occurs. It is shielded from interruption, but once its six clocks are done, interrupts can occur. Interrupts now work with XBYTE/SKIP/SKIPF/EXECF code. This was really important for single-stepping. The caveat for XBYTE/SKIP/SKIPF/EXECF code is that CALLs are allowed, but they must be absolute in all cases but "SKIP".
I need to make a new release and update the Google doc file to reflect the latest functionality. I will do that later this week.
Besides the SKIPF restriction on relative calls, I've also run into issues with porting self-modifying P1 code and with generating code at run time where calls and jumps have to be absolute.
Perhaps it makes sense for the absolute form of call/jmp to be the default (as it is in P1) and the relative to be either another opcode or selected via modifying the operand. Personally I'd like a different opcode. I think it would make these kinds of restrictions easier to explain, and also just make the code easier to read.
(No hardware change proposed here, just an assembler change!)
Besides the SKIPF restriction on relative calls, I've also run into issues with porting self-modifying P1 code and with generating code at run time where calls and jumps have to be absolute.
Perhaps it makes sense for the absolute form of call/jmp to be the default (as it is in P1) and the relative to be either another opcode or selected via modifying the operand. Personally I'd like a different opcode. I think it would make these kinds of restrictions easier to explain, and also just make the code easier to read.
(No hardware change proposed here, just an assembler change!)
That would be an improvement over what is there now.
Other MCUs use ACALL for absolute call, and RJMP or SJMP for relative.
Of course, most every other assembler I've ever seen uses this cleaner form, devoid of the distracting character-chaff
Besides the SKIPF restriction on relative calls, I've also run into issues with porting self-modifying P1 code and with generating code at run time where calls and jumps have to be absolute.
Perhaps it makes sense for the absolute form of call/jmp to be the default (as it is in P1) and the relative to be either another opcode or selected via modifying the operand. Personally I'd like a different opcode. I think it would make these kinds of restrictions easier to explain, and also just make the code easier to read.
(No hardware change proposed here, just an assembler change!)
That would be an improvement over what is there now.
Other MCUs use ACALL for absolute call, and RJMP or SJMP for relative.
Of course, most every other assembler I've ever seen uses this cleaner form, devoid of the distracting character-chaff
CALL Label2
ACALL Label2
Label2:
I was just reviewing the instructions to see about CALL/ACALL/RCALL. I remember that I've done this in the past, but I'm always stumped because the {#}S-address instructions are absolute for registers and relative for immediates. How to slice this pie with different mnemonics?
I was just reviewing the instructions to see about CALL/ACALL/RCALL. I remember that I've done this in the past, but I'm always stumped because the {#}S-address instructions are absolute for registers and relative for immediates. How to slice this pie with different mnemonics?
Assemblers I'm used to using, appear broadly like this :
ISTR there are issues with the @Rn, but ICALL could be clear enough for Indirect Call , or ICALL [Rn] if it needs to be even more obvious ?
Most MCUs have separate segments for CODE and REG/DATA, so that tends to make separations clearer for Assemblers to check.
However, in P2 COGs the CODE and REG space are rather on top of each other, but it may help to introduce the concepts of segments, as REG means explicitly 'place in COG', whilst COG/LUT/HUB exec on P2 means code could sensibly be placed in any, or all, of those areas.
This becomes like a type check, and ICALL above would only accept a register param, but if someone really did want to use the contents at label 2 as a pointer, they could do something broadly like
RegAbs REG 0x15 // address 0x15 as register
RegInCode REG Label2 // Use Label2 as address
CSEG
LoopForever:
ICALL RegAbs // calls to addr in [0x15]
ICALL RegInCode // Calls to addr in Label2, but gives a linker error if final Label2 resolves outside REG space.
ICALL LoopForever // Gives error, as REG expected, but got code label.
Label2:
DW LoopForever // Fill this code with something legal, but silly
Using SETQ or SETQ2 with Q[9]=1 would seem to be the sensible way to enable CZ writing in XBYTE. This is a bit of a dummy's question: if the D in SETQ/SETQ2 is 9-bit immediate, are the top 23 bits written to Q all zero, ensuring that XBYTE will not modify CZ?
Is CZ writing in XBYTE optional now, or is this yet to be done?
From a previous reply, a RET to $1F8-$1FF always starts a new XBYTE, even if there are '1' bits remaining in the skip pattern. Sometimes this early termination must occur inside a called subroutine. Assuming no nesting, is there any reason why the following shouldn't work?
' skipsub is routine called from SKIPF sequence
skipsub ...
' discard return address and start next XBYTE
_ret_ pop temp
Comments
There are currently two SKIP/SKIPF situations in which interrupts are delayed:
1) On the SKIP/SKIPF instruction, itself.
2) When the <next> instruction is getting cancelled.
#2 was just added yesterday to make things work in cases where the first skip bit is 1. I may now be able to get rid of #1. I will try that today.
Thanks, Chip.
_______________________________________
I'm the same person as TonyB but from now on I'll have to be TonyB_
I forgot my password and registered email address has been shut down!
Something not mentioned so far regarding skipping, I think, is that an interrupt routine could change the skip patterns deliberately by executing SKIPF, for example in response to external events. In theory a skip sequence could be extended ad infinitum but probably not beyond.
I just spent the last day and a half hunting down a bug involving SKIPF/EXECF/BYTEX and interrupts. The solution was to inhibit skip advancement, rather than delaying interrupts, when the interrupt circuit wants to insert its CALLD into the pipeline. This should make single-stepping more sensible.
I will post a new Prop123-A9 image later today.
Ozpropdev, if you could try it out, that would be great.
Here it is:
https://drive.google.com/file/d/0B9NbgkdrupkHTE9aN3hlbTdJYXM/view?usp=sharing
You should find the single-step behavior to be more sensible now.
The "dummy" step that appeared in the previous SKIPF tests is now fixed.
What has remained the same is the first instruction after a SKIP{F} is executed but stepped over.
The included test runs a SKIP and SKIPF code snippet in COG, HUB and LUT exec modes.
All actions operate as expected except for the initial first step.
Code outputs @115200 baud and press "*" to step through code.
Try this one:
https://drive.google.com/file/d/0B9NbgkdrupkHSXRkSVFaWEpDeWs/view?usp=sharing
It should not have any weirdness, at all.
Test code runs fine.
Looks good.
I'll throw some more test code at it to confirm but i'm pretty confident you've nailed it.
Test output snippet here shows step after SKIP{F} is correct now.
Thanks! :cool:
We now see the instruction after a skip Ok except if the first SKIP bit is '1' in SKIPF a "dummy" step is generated.
I don't think it's possible to improve it. The reason is that in the SKIPF instruction cycle, we must both cancel the next instruction and advance the PC by some variable amount. After that, we just advance the PC variably.
What I have now looks prettiest for single-stepping, but has caused a critical path that I hope to resolve. If I can't resolve it, we will go back to the way it was just before, where it always pauses on the instruction after SKIPF.
As long as the behaviour is predictable, and actually executes correctly, the Debug could fix-up any 1-opcode offsets that result from 'too many balls in the air' ?
Once you have the complex stuff nailed, and have Spin2 done, for a more lightweight diversion you could try PBASIC bytecodes thru the SKIPF engine ?
That gives another (simple) language test point, and you can benchmark P2 vs the venerable Stamps.
As JMG pointed out, as long as the behaviour is predictable and documented we can make our debuggers adjust accordingly.
Sorry it's been such a headache.
And could shut up all the questions about the next stamp?
I really like it. And @Chip is the only one who understands the PBASIC interpreter. Not sure how the language needs to change to accommodate the way bigger Memory, speed and multicore, but even running PBASIC on a P2 would be fantastic.
And would be a nice way to use smaller P2-Family Variants...
Enjoy!
Mike
I found CALL's seem to be OK within a SKIP sequence but fail in a SKIPF sequence.
That's in real time as well as single step.
for example
Those "CALL #address" instructions are relative. Use the "\" before the address to make them absolute:
It should work, then.
All calls from the skipped-instruction section must be either "#\" or register, in which either case the address is absolute.
Looks like I've got something I want to try. Have followed thos, but did not write code.
Also, I'm unclear on interrupts. Where do things stand there? Does XBYTE come first, interrupts first, or first come, first serve?
XBYTE could be considered a "virtual instruction" that executes when a RET to $1F8..$1FF occurs. It is shielded from interruption, but once its six clocks are done, interrupts can occur. Interrupts now work with XBYTE/SKIP/SKIPF/EXECF code. This was really important for single-stepping. The caveat for XBYTE/SKIP/SKIPF/EXECF code is that CALLs are allowed, but they must be absolute in all cases but "SKIP".
I need to make a new release and update the Google doc file to reflect the latest functionality. I will do that later this week.
Thanks
Perhaps it makes sense for the absolute form of call/jmp to be the default (as it is in P1) and the relative to be either another opcode or selected via modifying the operand. Personally I'd like a different opcode. I think it would make these kinds of restrictions easier to explain, and also just make the code easier to read.
(No hardware change proposed here, just an assembler change!)
Eric
Other MCUs use ACALL for absolute call, and RJMP or SJMP for relative.
Of course, most every other assembler I've ever seen uses this cleaner form, devoid of the distracting character-chaff
Last digit of SETQ is incorrect in bytecode[7:2] line on p.18 of v19 doc.
Also MODCZ operand info here needs adding to doc or instructions.
Okay. Thanks. I'll fix that.
I was just reviewing the instructions to see about CALL/ACALL/RCALL. I remember that I've done this in the past, but I'm always stumped because the {#}S-address instructions are absolute for registers and relative for immediates. How to slice this pie with different mnemonics?
Assemblers I'm used to using, appear broadly like this :
ISTR there are issues with the @Rn, but ICALL could be clear enough for Indirect Call , or ICALL [Rn] if it needs to be even more obvious ?
Most MCUs have separate segments for CODE and REG/DATA, so that tends to make separations clearer for Assemblers to check.
However, in P2 COGs the CODE and REG space are rather on top of each other, but it may help to introduce the concepts of segments, as REG means explicitly 'place in COG', whilst COG/LUT/HUB exec on P2 means code could sensibly be placed in any, or all, of those areas.
This becomes like a type check, and ICALL above would only accept a register param, but if someone really did want to use the contents at label 2 as a pointer, they could do something broadly like
I made some efficiency changes to the SKIP/SKIPF/EXECF/XBYTE circuitry. Could you please see if this checks out okay on your end?
https://drive.google.com/file/d/0B9NbgkdrupkHU01ydXdtOWhWdTA/view?usp=sharing
Thanks.
Is CZ writing in XBYTE optional now, or is this yet to be done?
From a previous reply, a RET to $1F8-$1FF always starts a new XBYTE, even if there are '1' bits remaining in the skip pattern. Sometimes this early termination must occur inside a called subroutine. Assuming no nesting, is there any reason why the following shouldn't work?