Today's challenge is to subtract a signed byte from a constant yielding a two-byte number.
W0 := 258 - S1;
First, a straightforward translation for the 6800. The sign extension of the byte in the variable is done first so that the carry flag from subtracting the low bytes is not lost.
Code:
0029 86 01 [2] 00043 ldaa #1
002B C6 7F [2] 00044 ldab #$7F ; Thanks Mike B!
002D D1 16 [3] 00045 cmpb S1
002F C2 7F [2] 00046 sbcb #$7F
0031 10 [2] 00047 sba
0032 C6 02 [2] 00048 ldab #2
0034 D0 16 [3] 00049 subb S1
0036 82 00 [2] 00050 sbca #0
That does not look too bad. Adding the negative of a number is the same as subtracting it so try that...
Code:
0029 86 7F [2] 00043 ldaa #$7F ; Thanks Mike B!
002B 91 16 [3] 00044 cmpa S1
002D 82 7F [2] 00045 sbca #$7F
002F 40 [2] 00046 nega
0030 8B 01 [2] 00047 adda #1
0032 C6 02 [2] 00048 ldab #2
0034 D0 16 [3] 00049 subb S1
0036 82 00 [2] 00050 sbca #0
Did we gain anything? No, but look at it some more.
The sign extension of a negative number is $FF and 0 for a positive number. Negating that, we should get 0 for a positive number and 1 for a negative one. There is an easy way to get there.
Code:
0029 86 7F [2] 00043 ldaa #$7F ; Thanks Mike B!
002B 91 16 [3] 00044 cmpa S1
002D 89 81 [2] 00045 adca #$81
002F 8B 01 [2] 00046 adda #1
0031 C6 02 [2] 00047 ldab #2
0033 D0 16 [3] 00048 subb S1
0035 82 00 [2] 00049 sbca #0
Surely something can be done about those consecutive adds.
Code:
00031 * W0 := 258 - S1;
00032
00033 * * 0 := v W0 -> 1
00034 * * 1 L r 2
00035
00036 * * 2 L c 258 -> 3
00037 * * 3 - v S1
00038
00039
00040 * 1 L r 2
00041 * 2 L c 258 -> 3
00042 * 3 - v S1
0029 86 7F [2] 00043 ldaa #$7F ; Thanks Mike B!
002B 91 16 [3] 00044 cmpa S1
002D 89 82 [2] 00045 adca #130
002F C6 02 [2] 00046 ldab #2
0031 D0 16 [3] 00047 subb S1
0033 82 00 [2] 00048 sbca #0
00049 * 0 := v W0 -> 1
0035 97 0D [4] 00050 staa W0
0037 D7 0E [4] 00051 stab W0+1
Now do it on the 6502.
Code:
0029 A9 7F [2] 00043 lda #$7F ; Thanks Mike B!
002B C5 16 [3] 00044 cmp S1
002D E9 7F [2] 00045 sbc #$7F
002F 49 FF [2] 00046 eor #$FF
0031 18 [2] 00047 clc
0032 69 02 [2] 00048 adc #2
0034 A8 [2] 00049 tay
0035 38 [2] 00050 sec
0036 A9 02 [2] 00051 lda #2
0038 E5 16 [3] 00052 sbc S1
003A AA [2] 00053 tax
003B 98 [2] 00054 tya
003C E9 00 [2] 00055 sbc #0
Wow! That is ugly.
Because the carry flag following the comparison is opposite most other processors, an addition does not get us there. Resort to a branch.
Code:
00031 ; W0 := 258 - S1;
00032
00033 ; ; 0 := v W0 -> 1
00034 ; ; 1 L r 2
00035
00036 ; ; 2 L c 258 -> 3
00037 ; ; 3 - v S1
00038
00039
00040 ; 1 L r 2
00041 ; 2 L c 258 -> 3
00042 ; 3 - v S1
0029 A0 01 [2] 00043 ldy #1
002B 24 16 [3] 00044 bit S1
002D 10 01 (0030) [2/3] 00045 bpl 2f
002F C8 [2] 00046 iny
0030 00047 2:
0030 38 [2] 00048 sec
0031 A9 02 [2] 00049 lda #2
0033 E5 16 [3] 00050 sbc S1
0035 AA [2] 00051 tax
0036 98 [2] 00052 tya
0037 E9 00 [2] 00053 sbc #0
00054 ; 0 := v W0 -> 1
0039 86 0D [3] 00055 stx W0
003B 85 0E [3] 00056 sta W0+1