Skip to navigation

Maths (Geometry): GetAngleFromCoords (Part 2 of 3)

Name: GetAngleFromCoords (Part 2 of 3) [Show more] Type: Subroutine Category: Maths (Geometry) Summary: Overflow and accuracy calculations
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
\ We now do two more shift-and-subtracts to see if we \ can should make the result more accurate in part 3 \ with interpolation and rounding ROL A \ Repeat the shift-and-subtract loop for the ninth BCS P%+6 \ shift, but without updating the result in T CMP V BCC P%+5 SBC V SEC ROR G \ Shift the carry into bit 7 of G, so it contains the \ result from shifting and subtracting bit 8 ROL A \ Repeat the shift-and-subtract loop for the tenth BCS gang7 \ shift, but without subtracting or updating the result CMP V \ in T .gang7 ROR G \ Shift the carry into bit 7 of G, so it contains the \ result from shifting and subtracting the tenth shift, \ and the result from the ninth shift is now in bit 6 \ of G \ \ So G now contains two results bits as follows: \ \ * Bit 6 is the first extra bit from the result, \ and if it is set then we apply interpolation to \ the result in part 3 \ \ * Bit 7 is the second extra bit from the result, \ and if it is set then we apply rounding to the \ result in part 3 \ \ We use these below to work out whether to interpolate \ results from the arctan lookup table, to improve the \ accuracy of the result LDA T \ Set A to the result of the division we did above, so \ we now have the following: \ \ A = 256 * (A T) / (V W) \ \ but with bit 5 clear rather than the actual result \ and the next two result bits in bits 6 and 7 of Q .gang8 \ We now use the result of the third shift of the \ shift-and-subtract calculation to set bit 5 in the \ result, which we cleared in the calculation above PLP \ Retrieve the result bit from the third shift, which \ we stored on the stack in part 1 \ \ This bit represents the third bit pushed into the \ result, so that's what should be bit 5 of the result \ \ It is now in the C flag (because it was in the C flag \ when we performed the PHP to push it onto the stack) BCC gang9 \ If the C flag is clear then bit 5 of the result should \ remain clear, so skip the following \ Otherwise bit 5 of the result should be set, which we \ can do with the following addition (in which we know \ that the C flag is set, as we just passed through a \ BCC instruction) ADC #%00100000 - 1 \ Set A = A + %00100000 - 1 + C \ = A + %00100000 \ \ If we get here having done all ten shifts, then we \ know that bit 5 of the result in A is clear, as we \ cleared it with the ASL T instruction just after gang6 \ above, so this just sets bit 5 of the result in A \ without any risk of the addition overflowing \ \ If, however, we get here by aborting the sequence of \ shifts after the second shift and jumping to gang10, \ then we have already set bit 5 of the result with an \ ORA instruction in gang10 before jumping back to \ gang8, so there is a possibility for this addition to \ overflow .gang9 BCC gang11 \ If the above addition was skipped, or it was applied \ and didn't overflow, then jump to gang11 to continue \ with the calculation \ If we get here then the above addition overflowed, so \ we return the highest angle possible from the table, \ which is 45 degrees LDA #255 \ Set angleTangent = 255, which is the closest we can STA angleTangent \ get to the tangent of 45 degrees, which should really \ be represented by (1 0) in our scale LDA #&00 \ Set angle(Hi Lo) = (&20 0) STA angleLo \ LDA #&20 \ This represents an angle of 45 degrees, as a full STA angleHi \ circle of 360 degrees is represented by (1 0 0), and: \ \ 360 degrees / 8 = 45 \ \ 256 / 8 = &20 RTS \ Return from the subroutine .gang10 \ If we get here then we have stopped shifting and \ subtracting after just three shifts \ \ We stored the first two shifts in T, but didn't store \ the third shift in T LDA #0 \ Clear bits 6 and 7 of G to indicate that we should not STA G \ apply interpolation or rounding in part 3 ROR T \ Set A to the bottom two bits of T, which is the same ROR A \ result as if we had shifted T left through the rest of ROR T \ the shift-and-subtract process that we've skipped ROR A ORA #%00100000 \ Set bit 5 of the result in A \ \ So we now have the result of the division in A JMP gang8 \ Jump to gang8 to continue the processing from the end \ of the division process