If you don't need to support signed integers, that routine can be adapted to take any two unsigned numbers whose sum does not exceed 255, at the extra cost of 12 to 15 T-states and 4 bytes. It's something I figured out about a year after releasing a 3D game which used this routine quite heavily - prior to my realisation, I had been truncating my inputs to fit between 0 to 63 and then afterwards bodging on an extra binary digit of precision at an average cost of 55.5 T-states, but it was still faster than doing it without a table.
Code: Select all
ld e,a
sub d ; Work out (a-b)
jr nc,$+4 ; Jump forward if positive
neg ; Negate to make this positive
ld h,d_multab/256
ld l,a ; Form address to quarter-square table
ld c,(hl)
inc h
ld b,(hl) ; Load ((a-b)^2)/4 into BC
ld a,e
add a,d ; Work out (a+b)
ld l,a
ld e,(hl)
dec h
ld l,(hl)
ld h,e ; Load ((a+b)^2)/4 into HL
sbc hl,bc ; Result = ((a+b)^2)/4 - ((a-b)^2)/4
d_multab:
; Aligned to 256-byte page
db $00, $00, $01, $02, $04, $06, $09, $0c, $10, $14, $19, $1e, $24, $2a, $31, $38
db $40, $48, $51, $5a, $64, $6e, $79, $84, $90, $9c, $a9, $b6, $c4, $d2, $e1, $f0
db $00, $10, $21, $32, $44, $56, $69, $7c, $90, $a4, $b9, $ce, $e4, $fa, $11, $28
db $40, $58, $71, $8a, $a4, $be, $d9, $f4, $10, $2c, $49, $66, $84, $a2, $c1, $e0
db $00, $20, $41, $62, $84, $a6, $c9, $ec, $10, $34, $59, $7e, $a4, $ca, $f1, $18
db $40, $68, $91, $ba, $e4, $0e, $39, $64, $90, $bc, $e9, $16, $44, $72, $a1, $d0
db $00, $30, $61, $92, $c4, $f6, $29, $5c, $90, $c4, $f9, $2e, $64, $9a, $d1, $08
db $40, $78, $b1, $ea, $24, $5e, $99, $d4, $10, $4c, $89, $c6, $04, $42, $81, $c0
db $00, $40, $81, $c2, $04, $46, $89, $cc, $10, $54, $99, $de, $24, $6a, $b1, $f8
db $40, $88, $d1, $1a, $64, $ae, $f9, $44, $90, $dc, $29, $76, $c4, $12, $61, $b0
db $00, $50, $a1, $f2, $44, $96, $e9, $3c, $90, $e4, $39, $8e, $e4, $3a, $91, $e8
db $40, $98, $f1, $4a, $a4, $fe, $59, $b4, $10, $6c, $c9, $26, $84, $e2, $41, $a0
db $00, $60, $c1, $22, $84, $e6, $49, $ac, $10, $74, $d9, $3e, $a4, $0a, $71, $d8
db $40, $a8, $11, $7a, $e4, $4e, $b9, $24, $90, $fc, $69, $d6, $44, $b2, $21, $90
db $00, $70, $e1, $52, $c4, $36, $a9, $1c, $90, $04, $79, $ee, $64, $da, $51, $c8
db $40, $b8, $31, $aa, $24, $9e, $19, $94, $10, $8c, $09, $86, $04, $82, $01, $80
db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $02, $02
db $02, $02, $02, $02, $02, $02, $02, $02, $03, $03, $03, $03, $03, $03, $03, $03
db $04, $04, $04, $04, $04, $04, $04, $04, $05, $05, $05, $05, $05, $05, $05, $06
db $06, $06, $06, $06, $06, $07, $07, $07, $07, $07, $07, $08, $08, $08, $08, $08
db $09, $09, $09, $09, $09, $09, $0a, $0a, $0a, $0a, $0a, $0b, $0b, $0b, $0b, $0c
db $0c, $0c, $0c, $0c, $0d, $0d, $0d, $0d, $0e, $0e, $0e, $0e, $0f, $0f, $0f, $0f
db $10, $10, $10, $10, $11, $11, $11, $11, $12, $12, $12, $12, $13, $13, $13, $13
db $14, $14, $14, $15, $15, $15, $15, $16, $16, $16, $17, $17, $17, $18, $18, $18
db $19, $19, $19, $19, $1a, $1a, $1a, $1b, $1b, $1b, $1c, $1c, $1c, $1d, $1d, $1d
db $1e, $1e, $1e, $1f, $1f, $1f, $20, $20, $21, $21, $21, $22, $22, $22, $23, $23
db $24, $24, $24, $25, $25, $25, $26, $26, $27, $27, $27, $28, $28, $29, $29, $29
db $2a, $2a, $2b, $2b, $2b, $2c, $2c, $2d, $2d, $2d, $2e, $2e, $2f, $2f, $30, $30
db $31, $31, $31, $32, $32, $33, $33, $34, $34, $35, $35, $35, $36, $36, $37, $37
db $38, $38, $39, $39, $3a, $3a, $3b, $3b, $3c, $3c, $3d, $3d, $3e, $3e, $3f, $3f