@TonyB_ said:
General comment:
Define S and D as Source and Destination at top, then use S and D thereafter to avoid longwinded text. E.g. "based on the bit pattern loaded from Destination" could be simply "based on the bit pattern in D."
Yeah, currently using Destination with the bold D. Jeff uses "Dest" and I've actually manually changed that in all the text that I've adapted from the official doc. But I'm kinda undecided, so I might change it afterall (to either Dest/Src or D/S - which do you think is better?)
I think plain D and S are best with no bolding. PASM instructions would be better in upper-case, same as doc and spreadsheet and your "titles". I have tested the use of SKIPF and EXECF when skipping is active and they work. (I do have an issue with one particular SKIPF but problem might not be SKIPF itself.) I have not tried skipping in an ISR to prove it doesn't work. Here is a distillation of SKIP down to bare minimum with all relevant info, I think:
SKIP {#}D - Skip (slow)
[encoding]
SKIP allows any of the next 32 instructions to be skipped if the corresponding bit = 1 in D, which is loaded into a shift register. Bit 0 controls skipping for the first instruction after SKIP and bit 31 the 32nd. A skipped instruction is effectively a NOP.
AUGS and AUGD are separate instructions, e.g.WRLONG ##1234, ##4568 consumes three skip bits. A call consumes only one skip bit for the entire routine. A skip sequence may be interrupted with no effect on the skip bits.
A call (or interrupt) suspends skipping until after the corresponding return and nested calls are allowed up to a depth of eight, matching the size of the hardware stack. Skipping continues after a jump and any remaining skip bits apply whether or not a conditional jump is made.
Skipping cannot be nested; SKIP ends any active or suspended skip sequence and starts a new one. SKIP #0 can be used to end skipping earlier than normal. SKIP does not work inside interrupt service routines.
Something I've never tried is calling a routine in hub RAM during a skip sequence. Also, using a conditional jump to exit a skip sequence can be a very real trap and EXECF {#}exit_address (all skip bits zero) is much safer.
@TonyB_ said:
General comment:
Define S and D as Source and Destination at top, then use S and D thereafter to avoid longwinded text. E.g. "based on the bit pattern loaded from Destination" could be simply "based on the bit pattern in D."
Yeah, currently using Destination with the bold D. Jeff uses "Dest" and I've actually manually changed that in all the text that I've adapted from the official doc. But I'm kinda undecided, so I might change it afterall (to either Dest/Src or D/S - which do you think is better?)
I think plain D and S are best with no bolding. PASM instructions would be better in upper-case, same as doc and spreadsheet and your "titles". I have tested the use of SKIPF and EXECF when skipping is active and they work. (I do have an issue with one particular SKIPF but problem might not be SKIPF itself.) I have not tried skipping in an ISR to prove it doesn't work. Here is a distillation of SKIP down to bare minimum with all relevant info, I think:
SKIP {#}D - Skip (slow)
[encoding]
SKIP allows any of the next 32 instructions to be skipped if the corresponding bit = 1 in D, which is loaded into a shift register. Bit 0 controls skipping for the first instruction after SKIP and bit 31 the 32nd. A skipped instruction is effectively a NOP.
AUGS and AUGD are separate instructions, e.g.WRLONG ##1234, ##4568 consumes three skip bits. A call consumes only one skip bit for the entire routine. A skip sequence may be interrupted with no effect on the skip bits.
A call (or interrupt) suspends skipping until after the corresponding return and nested calls are allowed up to a depth of eight, matching the size of the hardware stack. Skipping continues after a jump and any remaining skip bits apply whether or not a conditional jump is made.
Skipping cannot be nested; SKIP ends any active or suspended skip sequence and starts a new one. SKIP #0 can be used to end skipping earlier than normal. SKIP does not work inside interrupt service routines.
[example]
...
Thanks, that's probably a bit better worded than mine. Will take some of that.
Though most of the instruction descriptions are in active form i.e. "SETWTF does xyz"....
As said, sticking with the *D**estination for now for consistency until I come to a final decision (changing back from plain D/S to anything else would be obnoxious, so I defer for now.)
@TonyB_ said:
Something I've never tried is calling a routine in hub RAM during a skip sequence.
Oh, that works, at least indirectly (i.e. skip sequence calls function which then jumps into hubexec - happens all the time in my Z80 emulator). It'd be weird if it didn't work jumping directly into hubexec.
As said, i'm sticking with Destination for now because it's easy to bulk-replace it.
I prefer "internal stack" over "hardware stack"
Eliminated duplication between SKIP and SKIPF. They're literally next to each other and hyperlinked.
Minor style changes
<%=p2instrinfo('skip')%>
SKIP allows any of the next 32 instructions to be skipped if the corresponding bit is set (=1) in Destination. Bit 0 controls skipping for the first instruction after SKIP and bit 31 the 32nd. Destination is loaded into an internal shift register, changing it while SKIP is active has no effect.
The skipped instructions are treated similarly to ones whose if_* condition check isn't met, i.e. they take 2 cycles to execute and do consume any ALTx-type instruction preceding them.
A call (or interrupt) suspends skipping until after the corresponding return. Nested calls are allowed up to a depth of eight (matching the size of the internal stack). Skipping continues after a jump and any remaining skip bits apply whether or not a conditional jump is made.
Skipping cannot be nested; SKIP ends any active or suspended skip sequence and starts a new one. SKIP #0 can be used to end skipping earlier than normal. SKIP does not work inside interrupt service routines (TODO CONFIRM).
Note that AUGS and AUGD are separate instructions, e.g. WRLONG ##1234, ##4568 consumes three skip bits. A subroutine call consumes only one skip bit for the entire routine.
For example: (example code expunged for brevity)
<%=p2instrinfo('skipf')%>
SKIPF allows any of the next 32 instructions to be skipped if the corresponding bit is set (=1) in Destination. Bit 0 controls skipping for the first instruction after SKIPF and bit 31 the 32nd. Destination is loaded into an internal shift register, changing it while SKIPF is active has no effect.
SKIPF works similarly to SKIP, but differs in that it can completely eliminate instructions from the pipeline. The skipped instructions take zero cycles to execute and don't consume any ALTx-type instruction preceding them. This works by incrementing PC by more than one instruction at a time.
However, this instruction has some severe limitations/oddities:
It can only be used when executing from Cog or LUT memory. If it is used when executing from Hub memory, it acts as a normal SKIP.
Only 7 instructions can be fast-skipped at once. The 8th instruction will be skipped normally (i.e. takes 2 cycles and consumes ALTx).
The first instruction after SKIPF can not be fast-skipped. If its bit is set, it is skipped normally (see above)
Relative addressing should not be used for subroutine calls if the instruction after the call should be skipped (explicitly specify absolute addressing by writing #\label instead of #label). (TODO: What happens if this is violated?)
Absolute addressing (both direct immediates and indirect jumps through a register) should not be used for (non-call) branches where the first instruction after the branch should be skipped. (TODO: What happens if this is violated?)
"Yes" to the other grammar and spelling corrections. Cannot is correct in this context. Trust me. I'm a stickler for this stuff, but disdain any connection to Nazism.
Now checking for Oxford comma omissions -- a venal sin.
I maybe operate on ze germanophone englisch spezial. "kann nicht" -> "can not". Then again, assigning meaning to the (not-)presence of the space is somewhat harebrained.
In English, the hyphen (-) can act as a syntactic catalyst. I can imagine that things progressed from can not, to can-not, to cannot. It's the same with screwdriver: screw driver -> screw-driver -> screwdriver. Eventually hyphenated words like warm-up will drop the hyphen as it moves on to catalyze other grammatical reactions.
And I thought Deutsche was famous for its compound words, e.g.bleistiftspitzmaschine for pencil sharpener.
But more seriously, I'd argue that the contracted version flows better. Something something word shapes go straight through the brain.
Eitherhow (<- I believe I may have made this word up at some point), grammar particularities are lowest-priority. Better to get all the content where it belongs.
True, but isn't / doesn't / won't / etc. not appropriate in a formal document.
Says who? And what makes this a formal document? Anyway, according to plainlanguage.gov,
"While many legal authorities say that contractions don't belong in legal writing, Bryan Garner, a leading authority on legal writing, advocates their use as a way to make legal writing, including opinions and rules, less stuffy and more natural. Contractions make your writing more accessible to the user." [Emphasis mine.]
If it works for legal writing, it must certainly work here.
@Wuerfel_21 said:
However, this instruction has some severe limitations/oddities:
I don't like this sentence. SKIPF has some restrictions:
Relative addressing should not be used for subroutine calls if the instruction after the call should be skipped (explicitly specify absolute addressing by writing #\label instead of #label). (TODO: What happens if this is violated?)
Of course. But what actually happens? I think it causes a fast-skip to carry into the call (like how it works for relative jumps), but the details are probably somewhat more complicated.
Also, I just moved the allowed flags into the heading. Useful since some instructions (TESTB) differentiate variants based on flags. Though the "none/WC/WZ/WCZ" in the table was perhaps better at telling you that the flag is optional. Not that it really matters, since you'd pick up on that real quick when actually using P2ASM.
Of course. But what actually happens? I think it causes a fast-skip to carry into the call (like how it works for relative jumps), but the details are probably somewhat more complicated.
It's probably the same effect as what happens with a relative branch as the last instruction of a REP code block. The REP hardware is performing a relative change to the PC register and any branch doing the same will be combined and mess the address. Funnily, with the REP at least, it is predictable so could be compiled for.
Tried making the jump feature mobile-accessible (by way of having a position: fixed button that triggers it. (It displays on the top header on desktop, where it might alert someone to the presence of the feature if they got linked to a content page.)
Tell me if the animation on the indicator is too much...
(Also, yes, it will only say "HyperJump ready!" when it is actually ready. No javascript, no bueno.)
Regarding smartpin counter mode P_EVENTS_TICKS (%10010). The two sub-modes Y=0 vs Y=1 are dramatically different modes. I don't know why Chip stuck them together like that. Here's my short summary:
%10010_0, P_EVENTS_TICKS Y=%0xx ' Time: of X number of highs/pulses/steps
Y=%1xx ' Time: since latest high/rise/edge, with X timeout
@evanh said:
Regarding smartpin counter mode P_EVENTS_TICKS (%10010). The two sub-modes Y=0 vs Y=1 are dramatically different modes. I don't know why Chip stuck them together like that. Here's my short summary:
%10010_0, P_EVENTS_TICKS Y=%0xx ' Time: of X number of highs/pulses/steps
Y=%1xx ' Time: since latest high/rise/edge, with X timeout
Yea, kinda strange, but IMO they have to be documented together, since they share a mode symbol (P_EVENTS_TICKS)
@evanh said:
Regarding smartpin counter mode P_EVENTS_TICKS (%10010). The two sub-modes Y=0 vs Y=1 are dramatically different modes. I don't know why Chip stuck them together like that.
It's not only the ordering of the modes and sub modes... Every document so far only repeats Chip's descriptions. But honestly, I don't understand them at all. I mean I understand all the other smart pin modes but not the ones that measure time or count events. The descriptions explain what they physically do but I don't see any reason, intention or purpose in them.
IMHO, a clear documentation should explain it the other way round: Say, I want to measure a) duty cycle or b) measure frequency or c) phase relation. What mode should I use and how should I setup the registers? I don't like having to read all the docs and then guess which mode fits best what I need to do.
I think, whoever will write better doc about the smart modes than Chips original notes will really have to try it out. And this will need a lot of work and time.
Adas new approach could perhaps solve the problem, that information is found at so many different places. For example there are so many assembler instructions, which make only sense together with the very special hardware, so having separate hardware and assembler manuals is not very helpful.
Comments
I think plain D and S are best with no bolding. PASM instructions would be better in upper-case, same as doc and spreadsheet and your "titles". I have tested the use of SKIPF and EXECF when skipping is active and they work. (I do have an issue with one particular SKIPF but problem might not be SKIPF itself.) I have not tried skipping in an ISR to prove it doesn't work. Here is a distillation of SKIP down to bare minimum with all relevant info, I think:
SKIP {#}D - Skip (slow)
[encoding]
SKIP allows any of the next 32 instructions to be skipped if the corresponding bit = 1 in D, which is loaded into a shift register. Bit 0 controls skipping for the first instruction after SKIP and bit 31 the 32nd. A skipped instruction is effectively a NOP.
AUGS and AUGD are separate instructions, e.g.
WRLONG ##1234, ##4568
consumes three skip bits. A call consumes only one skip bit for the entire routine. A skip sequence may be interrupted with no effect on the skip bits.A call (or interrupt) suspends skipping until after the corresponding return and nested calls are allowed up to a depth of eight, matching the size of the hardware stack. Skipping continues after a jump and any remaining skip bits apply whether or not a conditional jump is made.
Skipping cannot be nested; SKIP ends any active or suspended skip sequence and starts a new one.
SKIP #0
can be used to end skipping earlier than normal. SKIP does not work inside interrupt service routines.[example]
...
Something I've never tried is calling a routine in hub RAM during a skip sequence. Also, using a conditional jump to exit a skip sequence can be a very real trap and
EXECF {#}exit_address
(all skip bits zero) is much safer.Thanks, that's probably a bit better worded than mine. Will take some of that.
Though most of the instruction descriptions are in active form i.e. "SETWTF does xyz"....
As said, sticking with the *D**estination for now for consistency until I come to a final decision (changing back from plain D/S to anything else would be obnoxious, so I defer for now.)
Oh, that works, at least indirectly (i.e. skip sequence calls function which then jumps into hubexec - happens all the time in my Z80 emulator). It'd be weird if it didn't work jumping directly into hubexec.
Also,
Is that true? I'd assume it isn't and that it just messes up if the non-irq code if it also uses SKIP.
Ok, what I've got now:
<%=p2instrinfo('skip')%>
SKIP allows any of the next 32 instructions to be skipped if the corresponding bit is set (=1) in Destination. Bit 0 controls skipping for the first instruction after SKIP and bit 31 the 32nd. Destination is loaded into an internal shift register, changing it while SKIP is active has no effect.
The skipped instructions are treated similarly to ones whose
if_*
condition check isn't met, i.e. they take 2 cycles to execute and do consume any ALTx-type instruction preceding them.A call (or interrupt) suspends skipping until after the corresponding return. Nested calls are allowed up to a depth of eight (matching the size of the internal stack). Skipping continues after a jump and any remaining skip bits apply whether or not a conditional jump is made.
Skipping cannot be nested; SKIP ends any active or suspended skip sequence and starts a new one.
SKIP #0
can be used to end skipping earlier than normal. SKIP does not work inside interrupt service routines (TODO CONFIRM).Note that AUGS and AUGD are separate instructions, e.g.
WRLONG ##1234, ##4568
consumes three skip bits. A subroutine call consumes only one skip bit for the entire routine.For example: (example code expunged for brevity)
<%=p2instrinfo('skipf')%>
SKIPF allows any of the next 32 instructions to be skipped if the corresponding bit is set (=1) in Destination. Bit 0 controls skipping for the first instruction after SKIPF and bit 31 the 32nd. Destination is loaded into an internal shift register, changing it while SKIPF is active has no effect.
SKIPF works similarly to SKIP, but differs in that it can completely eliminate instructions from the pipeline. The skipped instructions take zero cycles to execute and don't consume any ALTx-type instruction preceding them. This works by incrementing PC by more than one instruction at a time.
However, this instruction has some severe limitations/oddities:
#\label
instead of#label
). (TODO: What happens if this is violated?)Example: (example code expunged for brevity)
Isn't is just fine as a contraction for is not.
"Yes" to the other grammar and spelling corrections. Cannot is correct in this context. Trust me. I'm a stickler for this stuff, but disdain any connection to Nazism.
Now checking for Oxford comma omissions -- a venal sin.
-Phil
I maybe operate on ze germanophone englisch spezial. "kann nicht" -> "can not". Then again, assigning meaning to the (not-)presence of the space is somewhat harebrained.
True, but isn't / doesn't / won't / etc. not appropriate in a formal document.
In English, the hyphen (-) can act as a syntactic catalyst. I can imagine that things progressed from can not, to can-not, to cannot. It's the same with screwdriver: screw driver -> screw-driver -> screwdriver. Eventually hyphenated words like warm-up will drop the hyphen as it moves on to catalyze other grammatical reactions.
And I thought Deutsche was famous for its compound words, e.g. bleistiftspitzmaschine for pencil sharpener.
-Phil
yea sure
But more seriously, I'd argue that the contracted version flows better. Something something word shapes go straight through the brain.
Eitherhow (<- I believe I may have made this word up at some point), grammar particularities are lowest-priority. Better to get all the content where it belongs.
Says who? And what makes this a formal document? Anyway, according to plainlanguage.gov,
"While many legal authorities say that contractions don't belong in legal writing, Bryan Garner, a leading authority on legal writing, advocates their use as a way to make legal writing, including opinions and rules, less stuffy and more natural. Contractions make your writing more accessible to the user." [Emphasis mine.]
If it works for legal writing, it must certainly work here.
-Phil
I don't like this sentence.
SKIPF has some restrictions:
A. Your program will crash.
Of course. But what actually happens? I think it causes a fast-skip to carry into the call (like how it works for relative jumps), but the details are probably somewhat more complicated.
Also, I just moved the allowed flags into the heading. Useful since some instructions (TESTB) differentiate variants based on flags. Though the "none/WC/WZ/WCZ" in the table was perhaps better at telling you that the flag is optional. Not that it really matters, since you'd pick up on that real quick when actually using P2ASM.
BTW, I wouldn't advocate substituting can't for cannot in this context. Cannot carries a more proscriptive tone, which I think is appropriate here.
-Phil
It's probably the same effect as what happens with a relative branch as the last instruction of a REP code block. The REP hardware is performing a relative change to the PC register and any branch doing the same will be combined and mess the address. Funnily, with the REP at least, it is predictable so could be compiled for.
The way I was brung up I guess 😂🤣
@Wuerfel_21
No clue where you reside but your "maffs" thing cracked me up 😂
The worst thing about returning to Blighty is that I have to put up with this every day.
Fink (think)
Nuffink (nothing)
Bockle (bottle)
Keckle (kettle)
Ospicul (hospital)
I think a return to the USA needs to happen at some point.
Problem is that I'm a pureblood and that's not gonna change (no shite in these veins)
😎
Maybe just move 10 miles up the road to a new area with a different dialect, or 20 miles away and be almost incomprehensible ;-)
Tried making the jump feature mobile-accessible (by way of having a position: fixed button that triggers it. (It displays on the top header on desktop, where it might alert someone to the presence of the feature if they got linked to a content page.)
Tell me if the animation on the indicator is too much...
(Also, yes, it will only say "HyperJump ready!" when it is actually ready. No javascript, no bueno.)
Added some of the smart pin entries. https://p2docs.github.io/pin.html#smart-pin-modes Might rework the backend so I can have entries for all the pad ring modes, too.
This thing starts to be the best P2 doc available.
Regarding smartpin counter mode
P_EVENTS_TICKS (%10010)
. The two sub-modes Y=0 vs Y=1 are dramatically different modes. I don't know why Chip stuck them together like that. Here's my short summary:Yea, kinda strange, but IMO they have to be documented together, since they share a mode symbol (P_EVENTS_TICKS)
You want no background on both sides?
No, just want the white gone, the color boxes should stay (though perhaps ideally translucent).
It's not only the ordering of the modes and sub modes... Every document so far only repeats Chip's descriptions. But honestly, I don't understand them at all. I mean I understand all the other smart pin modes but not the ones that measure time or count events. The descriptions explain what they physically do but I don't see any reason, intention or purpose in them.
IMHO, a clear documentation should explain it the other way round: Say, I want to measure a) duty cycle or b) measure frequency or c) phase relation. What mode should I use and how should I setup the registers? I don't like having to read all the docs and then guess which mode fits best what I need to do.
That's where examples come in. And examples take a lot of extra work. Those will likely be in multiple extra docs like AN001 Propeller P8X32A Counters
I think, whoever will write better doc about the smart modes than Chips original notes will really have to try it out. And this will need a lot of work and time.
Adas new approach could perhaps solve the problem, that information is found at so many different places. For example there are so many assembler instructions, which make only sense together with the very special hardware, so having separate hardware and assembler manuals is not very helpful.
Though now that I think about it, it may just be better to not use images at all and (re-)create all the diagrams using SVGs or HTML