You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
dasm special-cases negative immediates in, for example...
VAL = -1
lda #VAL. ; assembles OK
Although numbers are stored internally as 32 bits, and by rights this would be equivalent to...
lda #$FFFFFFFF
... it assembles OK with dasm using the low bye ($FF) of the internal 32-byte number.
All good so far. It's detecting that the two's complement negative can be expressed as a single byte.
However, long ago when I was "fixing" things, and as a result we were required to write ...
VAL = -1
lda #VAL&$FF. ; nobody liked this
... well the "fix" was reverted/fixed, and we could once again write just ``lda #-1"
The rationale being that dasm would range-check (I am guessing) to detect if the operand was in the correct (signed or unsigned) range. And now to my point...
The valid signed range is of course 8 bits (2's complement). That is from $80 (-128 signed) to $FF (unsigned).
We should be able to use any value in that range without error. But not outside it.
It seems, however, that dasm is restricting the range to -$FF to +$FF, which is incorrect.
The correct range, as noted, is -$80 to +$FF.
As an example, the following assembles - and it should not...
lda #-130. ; whoops! Range should be -128 to 255 inclusive.
When I first implemented the overflow checks, I started out with a range check from -$80 to $FF. I later noticed that in the negative.asm test Peter F had included some checks that crossed below -$80 that he seems to expect to pass. Though I didn't understand the use case, I didn't want to break the existing assembly, so I relaxed the check from -$FF to $FF.
If someone wants to tighten it up again, I have no objection.
More specifically, the range allowed should be based on the 32 bit value, and then the low byte used.
So, -128 decimal to 255 decimal. Not $80 to $FF in hex values, but actually $FFFFFF80 to $000000FF hex.
I had a look just now, and the range check for negative operands is handled a bit differently, and should probably be made to match the .byte case. Here's what it currently looks like...
//FIX: for negative operands...
if ( (addrmode == AM_IMM8) && (sym->value <0) )
{
opsize=1;
sym->value=(char)(sym->value & 255);
break;
}
...after the dust has settled from the big merge, and I'll have a go at fixing it.
Activity
msaarna commentedon Aug 24, 2020
When I first implemented the overflow checks, I started out with a range check from -$80 to $FF. I later noticed that in the negative.asm test Peter F had included some checks that crossed below -$80 that he seems to expect to pass. Though I didn't understand the use case, I didn't want to break the existing assembly, so I relaxed the check from -$FF to $FF.
If someone wants to tighten it up again, I have no objection.
andrew-davie commentedon Aug 24, 2020
More specifically, the range allowed should be based on the 32 bit value, and then the low byte used.
So, -128 decimal to 255 decimal. Not $80 to $FF in hex values, but actually $FFFFFF80 to $000000FF hex.
msaarna commentedon Aug 25, 2020
Here's the original implementation for .byte and .word.
I had a look just now, and the range check for negative operands is handled a bit differently, and should probably be made to match the .byte case. Here's what it currently looks like...
...after the dust has settled from the big merge, and I'll have a go at fixing it.
andrew-davie commentedon Aug 26, 2020
Probably all it needs is...