I am not sure of a use for the instructions AND/OR/XOR of a [NOT]-BIT/PIN with the Z and/or C flag.
Still seems wrong to me but I guess since I cannot see a use, I can accept it being the wrong way around. It will catch people who use it tho'.
So now we have the MOV{C/Z}[N]{B/P} instructions...
So far, the use I have found for them have been to set the Z flag based on the bit/pin value. Here, I would like the Z flag to be set as it normally would ie Z=set=ZERO. How to solve this is easy with the compiler
I've just taken the MOVZxx instructions (from above) as the C is not at issue here.
MOVZB reg,bitindex ' Bit --> Z equiv TESTNB reg,bitindex WZ ' Z if !Bit=0
MOVZNB reg,bitindex ' !Bit --> Z equiv TESTB reg,bitindex WZ ' Z if Bit=0
MOVZP pinindex ' Pin --> Z equiv TESTNB pinindex WZ ' Z if !Pin=0
MOVZNP pinindex ' !Pin --> Z equiv TESTB pinindex WZ ' Z if Pin=0
MOV moves the bit/pin into the Z flag (ie Z=SET=1=zero-cond if bit/pin=1
TEST sets the Z flag according to the test result of bit/pin=0 (ie Z=SET=1=zero-cond if bit/pin=0)
So we have a pseudo code for testing the bit/pin which is equivalent to the inverse of moving the bit/pin.
CALLs that modify the flags write D[30] or S[30] to Z.
RCZL writes D[30] to Z.
RCZR writes D[0] to Z.
Z does not always mean zero.
I have just been looking thru the instruction set. There are more inconsistencies
I expect that the following are not what would normally be expected either (not tested)...
DRVZ {#}D {WCZ}
DRVNZ {#}D {WCZ}
My assumption would have been that if Z is set (ie means zero) that the pin would be set LOW. Is it set HIGH ???
Same applies to these ???
WRZ D
WRNZ D
And of course CALL and its variants are likely saving Z as "1" and not "0" as I would have previously expected. It's only a problem if you test these bits. It's fine for the RET instruction as a negative-negative will result in a positive.
The existing listed TESTxx instruction encodings have a hole in the CZ bit encodings of each one.
Assuming Chip likes the idea of absorbing C/Z into the mnemonics, I'm guessing Chip will remove the existing TESTxx mnemonics and issue a new, more verbose set as per Roys/Peters examples. ie: It won't be aliases.
The existing listed TESTxx instruction encodings have a hole in the CZ bit encodings of each one.
Assuming Chip likes the idea of absorbing C/Z into the mnemonics, I'm guessing Chip will remove the existing TESTxx mnemonics and issue a new, more verbose set as per Roys/Peters examples. ie: It won't be aliases.
The aliases will allow those (including myself) who want to test the bit/pin using the sensible and consistent settings of the Z flag.
It's all good and well until we start writing some real assembly code as garryj did and then we will see where it can be confusing or awkward. Maybe I might have a problem but then I think I will anyway, the P2 is radically different even from the P1.
Here is Roy's suggestion tidied up using mov instead of set.
MOVZB reg,bitindex ' Z = Bit
MOVZNB reg,bitindex ' Z = !Bit
MOVCB reg,bitindex ' C = Bit
MOVCNB reg,bitindex ' C = !Bit
ANDZB reg,bitindex ' Z = Z & Bit
ANDZNB reg,bitindex ' Z = Z & !Bit
ANDCB reg,bitindex ' C = C & Bit
ANDCNB reg,bitindex ' C = C & !Bit
ORZB reg,bitindex ' Z = Z | Bit
ORZNB reg,bitindex ' Z = Z | !Bit
ORCB reg,bitindex ' C = C | Bit
ORCNB reg,bitindex ' C = C | !Bit
XORZB reg,bitindex ' Z = Z ^ Bit
XORZNB reg,bitindex ' Z = Z ^ !Bit
XORCB reg,bitindex ' C = C ^ Bit
XORCNB reg,bitindex ' C = C ^ !Bit
MOVZP pinindex ' Z = Pin
MOVZNP pinindex ' Z = !Pin
MOVCP pinindex ' C = Pin
MOVCNP pinindex ' C = !Pin
ANDZP pinindex ' Z = Z & Pin
ANDZNP pinindex ' Z = Z & !Pin
ANDCP pinindex ' C = C & Pin
ANDCNP pinindex ' C = C & !Pin
ORZP pinindex ' Z = Z | Pin
ORZNP pinindex ' Z = Z | !Pin
ORCP pinindex ' C = C | Pin
ORCNP pinindex ' C = C | !Pin
XORZP pinindex ' Z = Z ^ Pin
XORZNP pinindex ' Z = Z ^ !Pin
XORCP pinindex ' C = C ^ Pin
XORCNP pinindex ' C = C ^ !Pin
This makes perfectly sense and I think it is not confusing, even to a hardcore assembly programmer. Remember SEC and CLC instructions on the 6502? While there was no SEZ and CLZ, I think most assembly programmers are very familier with the concept of setting the status flags in other ways than by arithmetical results.
I am not sure of a use for the instructions AND/OR/XOR of a [NOT]-BIT/PIN with the Z and/or C flag.
Still seems wrong to me but I guess since I cannot see a use, I can accept it being the wrong way around. It will catch people who use it tho'.
CALLs that modify the flags write D[30] or S[30] to Z.
RCZL writes D[30] to Z.
RCZR writes D[0] to Z.
Z does not always mean zero.
I have just been looking thru the instruction set. There are more inconsistencies
I expect that the following are not what would normally be expected either (not tested)...
DRVZ {#}D {WCZ}
DRVNZ {#}D {WCZ}
My assumption would have been that if Z is set (ie means zero) that the pin would be set LOW. Is it set HIGH ???
Same applies to these ???
WRZ D
WRNZ D
And of course CALL and its variants are likely saving Z as "1" and not "0" as I would have previously expected. It's only a problem if you test these bits. It's fine for the RET instruction as a negative-negative will result in a positive.
Maybe we should rename the Z flag into something that means "not zero", but in the positive, like "S" for "something", as opposed to nothing. Then, all this madness could go away.
CALLs that modify the flags write D[30] or S[30] to Z.
RCZL writes D[30] to Z.
RCZR writes D[0] to Z.
Z does not always mean zero.
I have just been looking thru the instruction set. There are more inconsistencies
I expect that the following are not what would normally be expected either (not tested)...
DRVZ {#}D {WCZ}
DRVNZ {#}D {WCZ}
My assumption would have been that if Z is set (ie means zero) that the pin would be set LOW. Is it set HIGH ???
Same applies to these ???
WRZ D
WRNZ D
And of course CALL and its variants are likely saving Z as "1" and not "0" as I would have previously expected. It's only a problem if you test these bits. It's fine for the RET instruction as a negative-negative will result in a positive.
Maybe we should rename the Z flag into something that means "not zero", but in the positive, like "S" for "something", as opposed to nothing. Then, all this madness could go away.
Z has always been at odds with C.
Perhaps it could be called "N" for Non-zero. Of course we already use "N" to be NOT although in that context it might be ok.
I really don't follow why we introduced the notion of shifting into Z rather than the standard way of Z being set in the result. RCZL/RCZR is the only place where the shifting notion has real meaning, and it could be covered here as being the same as Z is set if the shift result is Zero.
Currently, it does not matter how you cut it, Z is not consistent. Sometimes it means Zero, sometimes it means Non-Zero.
...
Currently, it does not matter how you cut it, Z is not consistent. Sometimes it means Zero, sometimes it means Non-Zero.
It's not sometimes, it's well defined:
For ALU operations the Z flag indicates if the resulting value is zero, that is: all bits are zero, not just a single bit. ALU operations work 32bit wide and all bits count, that is totally different from single bit operations.
For single bit operations it makes much more sense to use the true state of the bits for the universal C and Z flags. So they behave the same and are interchangeable.
Why is this such a problem for you with the Z flag, but not with the C flag? C is even more inconsistent, and should be always cleared for logical operations, because there is no overflow, and therefore no carry to indicate. For sure this would make it unusable.
I have the same question. The sorting Roy did makes a lot of sense!
For what it's worth, didn't we add the flag ops in response to a discussion about saving variable space some time back? That's where all this came from. Rather than maintain an entire long, and read / write to it, use the flags for more complex state information.
That also means we can ignore these instructions in most cases, just doing things in the usual way, does it not?
Chip,
Please don't change the Z flag. That's impacting almost all of the instructions/modifiers for an issue with just a small number of them. It will have ramifications across the board, including making porting from P1 harder.
Just rename the instructions, like I suggested and Peter revised.
Seconded. I would rather see the conflicting instructions removed before changing the Z flag.
I don't want to change the Z flag, believe me. That is opening a big can of worms.
We could rename those instructions, however. I would like to require WZ or WC after the operands, so that a quick look at the code will tell you a flag is being modified.
Can someone make a list of the proposed instructions, substituting the letter F for the letter C or Z? That would cut the mnemonics in half and give need for WZ/WC.
I really think it's better if you DO NOT put the WC/WZ on the end. That is part of the confusion. With WZ on there it should mean that the Z flag is set based on the result of the operation and not just part of the operation like it is in these instructions.
Having the flag name in the instruction should be enough to know that it's going to manipulate the flag.
If you insist on having something on the end to indicate it, then it should be a unique identifier that is not WZ/WC/WCZ. Perhaps WF? And keep the flag name in the instruction.
My recent post suggested a new suffix for these. Is that acceptable?
As I said, the problem is that having WZ on the suffix implies that the Z flag will be set according to the result (as in set when the result is 0) and not what will actually happen with these instructions.
That, to me, is the crux of the problem. So it needs to be something else that indicates it.
My recent post suggested a new suffix for these. Is that acceptable?
As I said, the problem is that having WZ on the suffix implies that the Z flag will be set according to the result (as in set when the result is 0) and not what will actually happen with these instructions.
That, to me, is the crux of the problem. So it needs to be something else that indicates it.
Also, I don't like GET* at all.
If people insist on thinking "GETB reg,bit WZ" is going to make Z = !bit, I can't help that.
"WF" as a suffix doesn't tell what flag is being affected.
My recent post suggested a new suffix for these. Is that acceptable?
As I said, the problem is that having WZ on the suffix implies that the Z flag will be set according to the result (as in set when the result is 0) and not what will actually happen with these instructions.
That, to me, is the crux of the problem. So it needs to be something else that indicates it.
Also, I don't like GET* at all.
To me (and I think it's safe to say, Chip), all the WC and WZ suffices indicate is that the particular flag is affected (may change). I humbly submit that the "set according to the result (as in set when the result is 0)" is an inference, not an implication.
To me, the crux of the problem is whether one can accept the idea of flag states being directly controlled, or being restricted to the ALU state output only. It seems obvious to me that we have some who can and some who can't (or won't), but only for the Z flag; Direct control of the C flag is accepted without question.
I find this inconsistency quite puzzling.
I think as a compromise, that the instruction should have the flag name in it also.
In your example: GETB reg,bit WZ ' Where is B being put? You seem to think the WZ explains that, but it doesn't. On every other ALU instruction WZ is not the destination, it's indicating that the Z flag will be written based on the result.
GETBZ reg, bit WZ ' this is better, in my opinion, because it's more clear. It's not ideal, but since you insist on having the WZ, this compromise is acceptable.
Also, I still think MOVBZ is more clear than GETBZ, but whatever, it's not as big a deal as the main issue.
I think as a compromise, that the instruction should have the flag name in it also.
In your example: GETB reg,bit WZ ' Where is B being put? You seem to think the WZ explains that, but it doesn't. On every other ALU instruction WZ is not the destination, it's indicating that the Z flag will be written based on the result.
GETBZ reg, bit WZ ' this is better, in my opinion, because it's more clear. It's not ideal, but since you insist on having the WZ, this compromise is acceptable.
Also, I still think MOVBZ is more clear than GETBZ, but whatever, it's not as big a deal as the main issue.
I kind of agree, but when it comes to the logical operations AND/OR/XOR, things get really hard to infer, since it seems most likely that the bit would be getting affected. That's why I like GET - it's very passive in regards to the bit.
'Too bad it couldn't have been an NZ flag. Then we wouldn't be having this discussion.
(Just kidding, Chip. Please don't even think about changing it.)
-Phil
Our problem is that in English and math parlance, we don't have a word that means NOT ZERO, so we can only express the function as ZERO in the negative.
I'm not yet persuaded we need to rake over things like this. Its not like P2 is a processor without quirks
I'm not so worried about what gets decided here, as I am about the precedent it sets for revisiting so many decisions from past years. Those decisions made some kind of marginal sense at the time, but its hard to respool the surrounding context that led to those decisions
so it makes sense to "carry" that form on with
GETBIT
GETPIN
One trick I learned many years ago to avoid confusion is to read the documentation.
I never assume that one MCU is going to behave the same as another.
Comments
Still seems wrong to me but I guess since I cannot see a use, I can accept it being the wrong way around. It will catch people who use it tho'.
So now we have the MOV{C/Z}[N]{B/P} instructions...
So far, the use I have found for them have been to set the Z flag based on the bit/pin value. Here, I would like the Z flag to be set as it normally would ie Z=set=ZERO. How to solve this is easy with the compiler
I've just taken the MOVZxx instructions (from above) as the C is not at issue here. So we have a pseudo code for testing the bit/pin which is equivalent to the inverse of moving the bit/pin.
I have just been looking thru the instruction set. There are more inconsistencies
I expect that the following are not what would normally be expected either (not tested)...
DRVZ {#}D {WCZ}
DRVNZ {#}D {WCZ}
My assumption would have been that if Z is set (ie means zero) that the pin would be set LOW. Is it set HIGH ???
Same applies to these ???
WRZ D
WRNZ D
And of course CALL and its variants are likely saving Z as "1" and not "0" as I would have previously expected. It's only a problem if you test these bits. It's fine for the RET instruction as a negative-negative will result in a positive.
Assuming Chip likes the idea of absorbing C/Z into the mnemonics, I'm guessing Chip will remove the existing TESTxx mnemonics and issue a new, more verbose set as per Roys/Peters examples. ie: It won't be aliases.
The aliases will allow those (including myself) who want to test the bit/pin using the sensible and consistent settings of the Z flag.
This makes perfectly sense and I think it is not confusing, even to a hardcore assembly programmer. Remember SEC and CLC instructions on the 6502? While there was no SEZ and CLZ, I think most assembly programmers are very familier with the concept of setting the status flags in other ways than by arithmetical results.
DRVZ will drive the pin high if the result was zero.(z=1)
Maybe we should rename the Z flag into something that means "not zero", but in the positive, like "S" for "something", as opposed to nothing. Then, all this madness could go away.
Perhaps it could be called "N" for Non-zero. Of course we already use "N" to be NOT although in that context it might be ok.
I really don't follow why we introduced the notion of shifting into Z rather than the standard way of Z being set in the result. RCZL/RCZR is the only place where the shifting notion has real meaning, and it could be covered here as being the same as Z is set if the shift result is Zero.
Currently, it does not matter how you cut it, Z is not consistent. Sometimes it means Zero, sometimes it means Non-Zero.
There is only the two flags. The Prop doesn't have a whole register full of condition codes bits, so the Z and C get repurposed.
It's not sometimes, it's well defined:
For ALU operations the Z flag indicates if the resulting value is zero, that is: all bits are zero, not just a single bit. ALU operations work 32bit wide and all bits count, that is totally different from single bit operations.
For single bit operations it makes much more sense to use the true state of the bits for the universal C and Z flags. So they behave the same and are interchangeable.
Why is this such a problem for you with the Z flag, but not with the C flag? C is even more inconsistent, and should be always cleared for logical operations, because there is no overflow, and therefore no carry to indicate. For sure this would make it unusable.
Andy
For what it's worth, didn't we add the flag ops in response to a discussion about saving variable space some time back? That's where all this came from. Rather than maintain an entire long, and read / write to it, use the flags for more complex state information.
That also means we can ignore these instructions in most cases, just doing things in the usual way, does it not?
Please don't change the Z flag. That's impacting almost all of the instructions/modifiers for an issue with just a small number of them. It will have ramifications across the board, including making porting from P1 harder.
Just rename the instructions, like I suggested and Peter revised.
I don't want to change the Z flag, believe me. That is opening a big can of worms.
We could rename those instructions, however. I would like to require WZ or WC after the operands, so that a quick look at the code will tell you a flag is being modified.
Can someone make a list of the proposed instructions, substituting the letter F for the letter C or Z? That would cut the mnemonics in half and give need for WZ/WC.
Having the flag name in the instruction should be enough to know that it's going to manipulate the flag.
If you insist on having something on the end to indicate it, then it should be a unique identifier that is not WZ/WC/WCZ. Perhaps WF? And keep the flag name in the instruction.
I see MOVB and think a bit is being moved, but from where to where?
Maybe this is better:
MOVBZ <-- move B to Z
MOVPZ <--- move P to Z
Having the flag in the instruction name MAKES it more clear.
Yes, I've been reading your posts.
As I've said, I would like to keep some flag suffix, so that it's obvious a flag is being affected.
I like MOVBZ/MOVPZ, except for their lack of flag suffix.
I agree that TESTB(N)/TESTP(N) is a little confusing because of the TEST(N) precedent.
These instructions are really 'getting' a bit and affecting a flag with it. I think GETB(N)/GETP(N) are most accurate and preserve the flag suffix.
As I said, the problem is that having WZ on the suffix implies that the Z flag will be set according to the result (as in set when the result is 0) and not what will actually happen with these instructions.
That, to me, is the crux of the problem. So it needs to be something else that indicates it.
Also, I don't like GET* at all.
If people insist on thinking "GETB reg,bit WZ" is going to make Z = !bit, I can't help that.
"WF" as a suffix doesn't tell what flag is being affected.
GET seems most accurate for what is going on.
(Just kidding, Chip. Please don't even think about changing it.)
-Phil
To me (and I think it's safe to say, Chip), all the WC and WZ suffices indicate is that the particular flag is affected (may change). I humbly submit that the "set according to the result (as in set when the result is 0)" is an inference, not an implication.
To me, the crux of the problem is whether one can accept the idea of flag states being directly controlled, or being restricted to the ALU state output only. It seems obvious to me that we have some who can and some who can't (or won't), but only for the Z flag; Direct control of the C flag is accepted without question.
I find this inconsistency quite puzzling.
In your example: GETB reg,bit WZ ' Where is B being put? You seem to think the WZ explains that, but it doesn't. On every other ALU instruction WZ is not the destination, it's indicating that the Z flag will be written based on the result.
GETBZ reg, bit WZ ' this is better, in my opinion, because it's more clear. It's not ideal, but since you insist on having the WZ, this compromise is acceptable.
Also, I still think MOVBZ is more clear than GETBZ, but whatever, it's not as big a deal as the main issue.
WZ and WC just mean that the corresponding flag gets written. What kind of operation is used to generate the C and Z flag depends on the instruction.
maybe GETNB instead of GETBN describes better what happens.
I kind of agree, but when it comes to the logical operations AND/OR/XOR, things get really hard to infer, since it seems most likely that the bit would be getting affected. That's why I like GET - it's very passive in regards to the bit.
Our problem is that in English and math parlance, we don't have a word that means NOT ZERO, so we can only express the function as ZERO in the negative.
I'm not yet persuaded we need to rake over things like this. Its not like P2 is a processor without quirks
I'm not so worried about what gets decided here, as I am about the precedent it sets for revisiting so many decisions from past years. Those decisions made some kind of marginal sense at the time, but its hard to respool the surrounding context that led to those decisions
We already have
GETWORD
GETBYTE
GETNIB
so it makes sense to "carry" that form on with
GETBIT
GETPIN
One trick I learned many years ago to avoid confusion is to read the documentation.
I never assume that one MCU is going to behave the same as another.