And for easy code review, it's really nice to have a column where flag writes stand out. Burying them inside the mnemonic hides where they are actually happening.
Seems a form that supports all of these is needed ?
C = B, C = !B
C = C AND B C = C AND !B
C = C OR B C = C OR !B
C = C XOR B C = C XOR !B
Z = B, Z = !B
Z = Z AND B Z = Z AND !B
Z = Z OR B Z = Z OR !B
Z = Z XOR B Z = Z XOR !B
B = B AND C B = B AND !C
B = B OR C B = B OR !C
B = B XOR C B = B XOR !C
B = B AND Z B = B AND !Z
B = B OR Z B = B OR !Z
B = B XOR Z B = B XOR !Z
B = 0 B = 1
B = C B = !C
B = Z B = !Z
B = !B
I added seven more.
And here are some other requirements:
- keep flag alterations in the far right column without forcing redundancy of flag expressions
- keep the operand only "D/{#}S'
Maybe this is better. It's shorter, and doesn't confuse with RDxxxx/WRxxxx:
That's quite good, because it can become as below, and the R/W prefixes make it clear which 'direction' things occur
RBIT D,{#}S {WC/ANDC/ORC/XORC,WZ/ANDZ/ORZ/XORZ} F = F AND B group
RBITN D,{#}S {WC/ANDC/ORC/XORC,WZ/ANDZ/ORZ/XORZ} F = F AND !B group
WBITF D,{#}S {ANDC/ORC/XORC, ANDZ/ORZ/XORZ} B = B AND F group
WBITNF D,{#}S {ANDC/ORC/XORC ,ANDZ/ORZ/XORZ} B = B AND !F group
WBITL D,{#}S B = 0
WBITH D,{#}S B = 1
WBITC D,{#}S B = C
WBITNC D,{#}S B = !C
WBITZ D,{#}S B = Z
WBITNZ D,{#}S B = !Z
WBITN D,{#}S B = !B
Jmg, you'd be using flag suffixes in flag-read situations. Better to have them appear only when a flag write is occurring.
To further clarify it is Flag Read, maybe follow your R.W convention like this
RBIT D,{#}S {WC/ANDC/ORC/XORC,WZ/ANDZ/ORZ/XORZ} F = F AND B group
RBITN D,{#}S {WC/ANDC/ORC/XORC,WZ/ANDZ/ORZ/XORZ} F = F AND !B group
WBITRF D,{#}S {ANDC/ORC/XORC,/ANDZ/ORZ/XORZ} B = B AND F group
WBITRNF D,{#}S {ANDC/ORC/XORC,/ANDZ/ORZ/XORZ} B = B AND !F group
WBITL D,{#}S B = 0
WBITH D,{#}S B = 1
WBITC D,{#}S B = C
WBITNC D,{#}S B = !C
WBITZ D,{#}S B = Z
WBITNZ D,{#}S B = !Z
WBITN D,{#}S B = !B
WBITRF = Write Bit Read Flag
WBITRNF = Write Bit Read !Flag
ANDC means AND with Carry, so that is still valid and ok, the final destination is set by the R.W starting the opcodes.
The trouble with MOV (or MOVB) is that you start needing a 3rd operand. And that 3rd operand is going to need to be C or Z (which I'd rather not tie up, as names) or CF or ZF, or 0 or 1, etc., along with ways to show !C and !Z. The syntax gets ugly really fast. But, if you had MOVB, you could also have ANDB/ORB/XORB with a standard operand format.
Sorry I meant the SET in SETBC/SETBNC/etc., as shown by jmg. It's best to get these bit mnemonics right and not worry about compatibility with DIR/OUT/FLT/DRV.
I know I keep asking but can all of the ANDB, ORB, XORB fit in?
I'm thinking now that BIT{L/H/C/NC/Z/NZ/RND/NOT} is actually quite sufficient, because we can do even more with conditionals to achieve things like ANDBC (IF_NC BITL). Plus, and importantly, we stay akin to the numerous {DIR/OUT/FLT/DRV}{L/H/C/NC/Z/NZ/RND/NOT} instructions, which are simple to look at and understand.
Sorry for all this fidgeting, Everyone. It's almost through.
Cluso99,
I'm thinking now that BIT{L/H/C/NC/Z/NZ/RND/NOT} is actually quite sufficient, ....
Not quite, shortfalls are :
* Conditionals may manage AND,OR,XOR to Bit but they cannot manage MOV
* Once you alias Logic via a Conditional, you lose free use of that field, for actual conditional operation.
One detail that appeals, is the ability to use both C and Z as parallel boolean accumulators, allowing more complex expressions to evaluate in boolean logic.
Don't we have BIT{L/H/C/NC/Z/NZ/RND/NOT} for move? Isn't that everything?
Yes, if those are included. I've got a little lost at what is 'in' and what is 'out' across all the many permutations, & renamings, but I do remember that the Full Bit Instructions had no operational blind spots, so it becomes an exercise in mnemonic naming to cover that.
To keep track, I like to include the boolean equation alongside the opcode when I post.
* 'BIT{L/H/C/NC/Z/NZ/RND/NOT} WC,WZ' will write the original bit to C and NZ.
* Conditionals allow complex operations: 'IF_C_NE_Z BITNOT D,{#}S WC,WZ' writes C^Z^bit into bit and returns the original bit value into C and NZ.
* MODCZ allows simultaneous operations on both C and Z for all purposes except register-bit-related.
With the "full" set I made, at first, you could do anything, as well, but you could only do ONE thing at a time. Period. This is richer, but there are three different ways things happen: TESTB{N}, BIT{x}, and MODCZ.
Also, we stay harmonized with the pin operators: TESTP/TESTPN is like TESTB/TESTBN and DIRx/OUTx/FLTx/DRVx is like BITx. I think it all fits together about as well as it can, this way.
That would be very good.
Which opcodes now cover these operations, and how do they present to the user ?
B = B AND F group
B = B AND !F group
eg
IF_Z_EQ_C B = B AND C
IF_LE B = B AND !Z
Here are the basic combinatorial logic functions between flags and bits:
IF_NC BITL D,{#}S 'B = B AND C
IF_C BITL D,{#}S 'B = B AND !C
IF_NZ BITL D,{#}S 'B = B AND Z
IF_Z BITL D,{#}S 'B = B AND !Z
IF_C BITH D,{#}S 'B = B OR C
IF_NC BITH D,{#}S 'B = B OR !C
IF_Z BITH D,{#}S 'B = B OR Z
IF_NZ BITH D,{#}S 'B = B OR !Z
IF_C BITNOT D,{#}S 'B = B XOR C
IF_NC BITNOT D,{#}S 'B = B XOR !C
IF_Z BITNOT D,{#}S 'B = B XOR Z
IF_NZ BITNOT D,{#}S 'B = B XOR !Z
TESTB D,{#}S ANDC 'C = C AND B
TESTBN D,{#}S ANDC 'C = C AND !B
TESTB D,{#}S ANDZ 'Z = Z AND B
TESTBN D,{#}S ANDZ 'Z = Z AND !B
TESTB D,{#}S ORC 'C = C OR B
TESTBN D,{#}S ORC 'C = C OR !B
TESTB D,{#}S ORZ 'Z = Z OR B
TESTBN D,{#}S ORZ 'Z = Z OR !B
TESTB D,{#}S XORC 'C = C XOR B
TESTBN D,{#}S XORC 'C = C XOR !B
TESTB D,{#}S XORZ 'Z = Z XOR B
TESTBN D,{#}S XORZ 'Z = Z XOR !B
I've got all this stuff redone using the flag suffixes and it works. I don't know how to do this any better.
Here are the bit operations. Note that for the TESTB{N} (read) instructions, you must pick either a C or Z suffix to affect a flag, causing one of the CZ bits to be set in the opcode.
For the BITx (write) instructions, you must use both WC and WZ, or neither. This allows the previous bit state to be optionally loaded into C and NZ.
Here are the pin instructions. They work the same as those above and have identical syntax.
TESTP{N} is like TESTB{N}, but just needs a pin number to read an INA/INB bit.
DIRx is like BITx above, but just needs a pin number to write a DIRA/DIRB bit.
OUTx is like BITx above, but just needs a pin number to write an OUTA/OUTB bit.
FLTx is like BITx above, but just needs a pin number to write an OUTA/OUTB bit and clear a DIRA/DIRB bit.
DRVx is like BITx above, but just needs a pin number to write an OUTA/OUTB bit and set a DIRA/DIRB bit.
If "WC,WZ" is used with DIRx, the original DIRA/DIRB bit will be written to C and NZ. For OUTx/FLTx/DRVx, the original OUTA/OUTB bit will be written to C and NZ.
I think this covers things really well and gets us a lot more flag logic than we had before. Thanks to all you guys for fretting over this and thinking about how this could work best. I know jmg would like more discrete operations, but this is quite sufficient, I think.
For the BITx (write) instructions, you must use both WC and WZ, or neither. This allows the previous bit state to be optionally loaded into C and NZ.
DOCS: Maybe that must use both WC and WZ can be simplified to a WPV or WLV or similar (Write Previous Value, Write Last Value etc), or even a WPCNZ if you want to be accurate ?
"WC,WZ or neither" is going to be hard to document, made more confusing by the fact WZ is not actually what happens, but WNZ.
Is that NOT Z effect still needed ? Was it there to allow a means to extract NOTBIT for later testing ? What code uses WPCNZ ?
Will encodings for
B = B OR !C
B = B XOR !Z
etc be given clearer, alias opcodes ?
DOCS: These encodings give no indications of the 'reach' of these opcodes, but seem to imply they can do more than they actually can.
TESTP I think is limited to 32bool or a 5b active index, and TESTP is limited to a 64bool or 6b active index.
Would the DOCS be better written like this, to show that ?
Where
~~~~sssss means 5 bit immediate, or lower 5 bits of S Reg
~~~dddddd means 6 bit immediate, or lower 6 bits of D Reg
(which opcode bit selects D/# in TESTP ?)
For the BITx (write) instructions, you must use both WC and WZ, or neither. This allows the previous bit state to be optionally loaded into C and NZ.
DOCS: Maybe that must use both WC and WZ can be simplified to a WPV or WLV or similar (Write Previous Value, Write Last Value etc), or even a WPCNZ if you want to be accurate ?
DOCS: These encodings give no indications of the 'reach' of these opcodes, but seem to imply they can do more than they actually can.
TESTP I think is limited to 32bool or a 5b active index, and TESTP is limited to a 64bool or 6b active index.
Would the DOCS be better written like this, to show that ?
Where
~~~~sssss means 5 bit immediate, or lower 5 bits of S Reg
~~~dddddd means 6 bit immediate, or lower 6 bits of D Reg
(which opcode bit selects D/# in TESTP ?)
I've tried "~" and "." and "X" for don't care bits, but best one to me is "-".
I think TESTB would be best documented as
TESTB D,S/# WC|WZ|ANDC|ANDZ|ORC|ORZ|XORC|XORZ
to show that a suffix is required.
Comments
I added seven more.
And here are some other requirements:
- keep flag alterations in the far right column without forcing redundancy of flag expressions
- keep the operand only "D/{#}S'
That's quite good, because it can become as below, and the R/W prefixes make it clear which 'direction' things occur
(ANDing and ORing WBIT can be done with conditionals.)
What will the mnemonics be for the INAND block?
To further clarify it is Flag Read, maybe follow your R.W convention like this WBITRF = Write Bit Read Flag
WBITRNF = Write Bit Read !Flag
ANDC means AND with Carry, so that is still valid and ok, the final destination is set by the R.W starting the opcodes.
How about MOV instead of SET?
Are there enough opcodes available?
What about compatibility with DIR/OUT/FLT/DRV mnemonics?
Looks good, very close, only the SETBC sounds too much like MAKE ONE, when it really means move... maybe this ?
The trouble with MOV (or MOVB) is that you start needing a 3rd operand. And that 3rd operand is going to need to be C or Z (which I'd rather not tie up, as names) or CF or ZF, or 0 or 1, etc., along with ways to show !C and !Z. The syntax gets ugly really fast. But, if you had MOVB, you could also have ANDB/ORB/XORB with a standard operand format.
I know I keep asking but can all of the ANDB, ORB, XORB fit in?
To summarize/simplify they become...
Nice!
I'm thinking now that BIT{L/H/C/NC/Z/NZ/RND/NOT} is actually quite sufficient, because we can do even more with conditionals to achieve things like ANDBC (IF_NC BITL). Plus, and importantly, we stay akin to the numerous {DIR/OUT/FLT/DRV}{L/H/C/NC/Z/NZ/RND/NOT} instructions, which are simple to look at and understand.
Sorry for all this fidgeting, Everyone. It's almost through.
* Conditionals may manage AND,OR,XOR to Bit but they cannot manage MOV
* Once you alias Logic via a Conditional, you lose free use of that field, for actual conditional operation.
One detail that appeals, is the ability to use both C and Z as parallel boolean accumulators, allowing more complex expressions to evaluate in boolean logic.
Don't we have BIT{L/H/C/NC/Z/NZ/RND/NOT} for move? Isn't that everything?
To keep track, I like to include the boolean equation alongside the opcode when I post.
* 'BIT{L/H/C/NC/Z/NZ/RND/NOT} WC,WZ' will write the original bit to C and NZ.
* Conditionals allow complex operations: 'IF_C_NE_Z BITNOT D,{#}S WC,WZ' writes C^Z^bit into bit and returns the original bit value into C and NZ.
* MODCZ allows simultaneous operations on both C and Z for all purposes except register-bit-related.
With the "full" set I made, at first, you could do anything, as well, but you could only do ONE thing at a time. Period. This is richer, but there are three different ways things happen: TESTB{N}, BIT{x}, and MODCZ.
Also, we stay harmonized with the pin operators: TESTP/TESTPN is like TESTB/TESTBN and DIRx/OUTx/FLTx/DRVx is like BITx. I think it all fits together about as well as it can, this way.
Which opcodes now cover these operations, and how do they present to the user ?
B = B AND F group
B = B AND !F group
eg
IF_Z_EQ_C B = B AND C
IF_LE B = B AND !Z
Keep in mind too much gymnastics makes code harder to read, and simply ends up not being used by Compilers..
The P2 doesn't have to be an 8051. They are < $1.00 so P2 won't be competing with the 8051.
Chipmas 2017 isn't looking likely anymore
The P1B or P2HOT is looking better all the time.
Here are the basic combinatorial logic functions between flags and bits:
Here are the assign-to-bits and assign-to-flags:
You can get more out of those using conditionals.
Here are the bit operations. Note that for the TESTB{N} (read) instructions, you must pick either a C or Z suffix to affect a flag, causing one of the CZ bits to be set in the opcode.
For the BITx (write) instructions, you must use both WC and WZ, or neither. This allows the previous bit state to be optionally loaded into C and NZ.
That should be pretty understandable.
Here are the pin instructions. They work the same as those above and have identical syntax.
TESTP{N} is like TESTB{N}, but just needs a pin number to read an INA/INB bit.
DIRx is like BITx above, but just needs a pin number to write a DIRA/DIRB bit.
OUTx is like BITx above, but just needs a pin number to write an OUTA/OUTB bit.
FLTx is like BITx above, but just needs a pin number to write an OUTA/OUTB bit and clear a DIRA/DIRB bit.
DRVx is like BITx above, but just needs a pin number to write an OUTA/OUTB bit and set a DIRA/DIRB bit.
If "WC,WZ" is used with DIRx, the original DIRA/DIRB bit will be written to C and NZ. For OUTx/FLTx/DRVx, the original OUTA/OUTB bit will be written to C and NZ.
I think this covers things really well and gets us a lot more flag logic than we had before. Thanks to all you guys for fretting over this and thinking about how this could work best. I know jmg would like more discrete operations, but this is quite sufficient, I think.
I'm compiling v19 now, for what it's worth.
"WC,WZ or neither" is going to be hard to document, made more confusing by the fact WZ is not actually what happens, but WNZ.
Is that NOT Z effect still needed ? Was it there to allow a means to extract NOTBIT for later testing ? What code uses WPCNZ ?
Will encodings for
B = B OR !C
B = B XOR !Z
etc be given clearer, alias opcodes ?
DOCS: These encodings give no indications of the 'reach' of these opcodes, but seem to imply they can do more than they actually can.
TESTP I think is limited to 32bool or a 5b active index, and TESTP is limited to a 64bool or 6b active index.
Would the DOCS be better written like this, to show that ?
Where
~~~~sssss means 5 bit immediate, or lower 5 bits of S Reg
~~~dddddd means 6 bit immediate, or lower 6 bits of D Reg
(which opcode bit selects D/# in TESTP ?)
Looking forward to taking V19 for a SPIN
Good point. I prefer WPCZ.
I've tried "~" and "." and "X" for don't care bits, but best one to me is "-".
I think TESTB would be best documented as
TESTB D,S/# WC|WZ|ANDC|ANDZ|ORC|ORZ|XORC|XORZ
to show that a suffix is required.
Putting these various ideas together: