Skip to navigation


Maths: ScaleDown (Part 4 of 4)

Name: ScaleDown (Part 4 of 4) [Show more] Type: Subroutine Category: Maths Summary: Scale the y-coordinate
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
.down18 \ We now shift the y-coordinate in (RR Q P) by Y \ places in the correct direction, discarding the \ fractional part in P when we are done, but only after \ rounding (RR Q) to the nearest integer TYA \ If Y < 0, jump to down21 to shift the y-coordinate BMI down21 \ right by Y places, with A set to Y BNE down19 \ If Y > 0, jump to down19 to shift the y-coordinate \ right by Y places ASL P \ Y = 0, so shift bit 7 of P into the C flag and jump JMP down23 \ to down23 to round the result to the nearest integer, \ without shifting the y-coordinate first .down19 \ We now shift (RR Q P) left by X places LDA Q \ Set (RR A P) = (RR Q P) .down20 ASL P \ Set (RR A P) = (RR A P) << 1 ROL A ROL RR DEY \ Decrement the shift counter BNE down20 \ Loop back until we have shifted left by Y places STA Q \ Set (RR Q P) = (RR A P) ASL P \ Shift bit 7 of P into the C flag, so it contains bit \ 7 of the fractional part JMP down23 \ Jump to down23 to round the result to the nearest \ integer .down21 \ If we get here then we want to shift the result right \ by the number of places in A, where A is negative EOR #&FF \ Set Y = -A so we can use it as a shift counter for the CLC \ number of places to shift ADC #1 TAY \ We now shift (RR Q P) right by Y places, and because \ RR = 0 and we are going to discard the fractional part \ in P, we only actually need to shift Q LDA Q \ Set A = Q .down22 LSR A \ Set A = A >> 1 DEY \ Decrement the shift counter BNE down22 \ Loop back until we have shifted right by Y places STA Q \ Set Q = A, so now we have shifted (RR Q) right by \ Y places, and the C flag is set to the last bit that \ we shifted out of Q, which would be bit 7 of the \ fractional part .down23 \ We now round up the result, if bit 7 of the fractional \ part is set \ The C flag contains the next bit that would have been \ left-shifted out of PP into the result in (RR Q), or \ right-shifted out of the result in (RR Q), so if that \ bit is set, we need to round up the result BCC down24 \ If the next bit is clear, then jump to return from the \ subroutine, as we do not need to round up the result INC Q \ Otherwise increment the low byte of the result in BNE down24 \ (RR Q) to round it up, and if we did that without \ overflowing, jump to down24 to return from the \ subroutine as we now have our result INC RR \ If the increment overflowed the low byte, increment \ the high byte of the result in (RR Q) to round it up LDA RR \ If the high byte is < &40, jump to down24 to return CMP #&40 \ from the subroutine as we now have our result BCC down24 LDA #&3F \ Otherwise set (RR Q) = &3FFF as the highest value we STA RR \ can return as the y-coordinate LDA #&FF STA Q .down24 RTS \ Return from the subroutine