Yeah, mine is lossy, but its very compact and tiny. The most I have seen it off is by 4 binary degrees but on average its usually less than 3. It is exact every 45 degrees. This is the routine I'm using:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| p_ArcTan: .db __ArcTanEnd-1-$ ex de,hl ;de = y pop hl ex (sp),hl ;hl = x push hl ld a,h ;\ xor d ; |Get pairity rla ;/ jr c,__ArcTanSS ;\ add hl,de ; | add hl,de ; | __ArcTanSS: ; | or a ; |hl = x +- y sbc hl,de ;/ ex de,hl ;de = x +- y ld b,6 ;\ __ArcTan64: ; | add hl,hl ; |hl = 64y djnz __ArcTan64 ;/ call $3F00+sub_SDiv ;hl = 64y/(x +- y) pop af ;\ rla ; |Right side, fine ret nc ;/ sbc a,a ;\ sub h ; |Reverse sign extend ld h,a ;/ ld a,l ;\ add a,128 ; |Add or sub 128 ld l,a ;/ ret __ArcTanEnd:
|
The arguments are currently backwards; (X,Y) instead of the traditional (Y,X). I'm not sure which one I'm going to use yet.