Skip to navigation

Aviator on the BBC Micro

Maths: ScaleDown (Part 3 of 4)

Name: ScaleDown (Part 3 of 4) [Show more] Type: Subroutine Category: Maths Summary: Scale the x-coordinate
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
.down12 \ We now shift the x-coordinate in (SS QQ PP) by X \ places in the correct direction, discarding the \ fractional part in PP when we are done, but only after \ rounding (SS QQ) to the nearest integer TXA \ If X < 0, jump to down15 to shift the x-coordinate BMI down15 \ right by X places, with A set to X BNE down13 \ If X > 0, jump to down13 to shift the x-coordinate \ left by X places ASL PP \ X = 0, so shift bit 7 of PP into the C flag and jump JMP down17 \ to down17 to round the result to the nearest integer, \ without shifting the x-coordinate first .down13 \ We now shift (SS QQ PP) left by X places LDA QQ \ Set (SS A PP) = (SS QQ PP) .down14 ASL PP \ Set (SS A PP) = (SS A PP) << 1 ROL A ROL SS DEX \ Decrement the shift counter BNE down14 \ Loop back until we have shifted left by X places STA QQ \ Set (SS QQ PP) = (SS A PP) ASL PP \ Shift bit 7 of PP into the C flag, so it contains bit \ 7 of the fractional part JMP down17 \ Jump to down17 to round the result to the nearest \ integer .down15 \ 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 X = -A so we can use it as a shift counter for the CLC \ number of places to shift ADC #1 TAX \ We now shift (SS QQ PP) right by X places, and because \ SS = 0 and we are going to discard the fractional part \ in PP, we only actually need to shift QQ LDA QQ \ Set A = QQ .down16 LSR A \ Set A = A >> 1 DEX \ Decrement the shift counter BNE down16 \ Loop back until we have shifted right by X places STA QQ \ Set QQ = A, so now we have shifted (SS QQ) right by \ X places, and the C flag is set to the last bit that \ we shifted out of QQ, which would be bit 7 of the \ fractional part .down17 \ 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 (SS QQ), or \ right-shifted out of the result in (SS QQ), so if that \ bit is set, we need to round up the result BCC down18 \ If the next bit is clear, then jump to down18 to move \ on to scaling the y-coordinate, as we do not need to \ round up the result INC QQ \ Otherwise increment the low byte of the result in BNE down18 \ (SS QQ) to round it up, and if we did that without \ overflowing, jump to down18 to move on to scaling the \ y-coordinate INC SS \ If the increment overflowed the low byte, increment \ the high byte of the result in (SS QQ) to round it up LDA SS \ If the high byte is < &40, jump to down18 to move on CMP #&40 \ to scaling the y-coordinate BCC down18 LDA #&3F \ Otherwise set (SS QQ) = &3FFF as the highest value we STA SS \ can return as the x-coordinate LDA #&FF STA QQ