This code appears in the following versions (click to see it in the source code):
Code variations between these versions are shown below.
Name: LL28 Type: Subroutine Category: Maths (Arithmetic) Summary: Calculate R = 256 * A / Q
Calculate the following, where A < Q: R = 256 * A / Q This is a sister routine to LL61, which does the division when A >= Q. If A >= Q then 255 is returned and the C flag is set to indicate an overflow (the C flag is clear if the division was a success). The result is returned in one byte as the result of the division multiplied by 256, so we can return fractional results using integers.
.LL28 CMP Q \ If A >= Q, then the answer will not fit in one byte, BCS LL2 \ so jump to LL2 to return 255
Returns: C flag Set if the answer is too big for one byte, clear if the division was a success
Other entry points: LL28+4 Skips the A >= Q check and always returns with C flag cleared, so this can be called if we know the division will work LL31 Skips the A >= Q check and does not set the R counter, so this can be used for jumping straight into the division loop if R is already set to 254 and we know the division will work
The LL28 routine in the advanced versions uses logarithms to speed up the multiplication.
Tap on a block to expand it, and tap it again to revert.
The Master version omits half of the logarithm algorithm when compared to the 6502SP version.
See below for more variations related to this code.
This variation is blank in the Cassette, Disc (flight), Disc (docked), Master and Electron versions.
BMI noddlog \ If the subtraction is negative, jump to noddlog
Code variation 5 of 8
See variation 4 above for details.
This variation is blank in the Cassette, Disc (flight), Disc (docked) and Electron versions.
Tap on a block to expand it, and tap it again to revert.
Code variation 6 of 8
See variation 4 above for details.
This variation is blank in the Cassette, Disc (flight), Disc (docked), Master and Electron versions.
.noddlog LDX widget \ Set A = high byte of log(A) - high byte of log(Q) LDA log,X LDX Q SBC log,X BCS LL2 \ If the subtraction fitted into one byte and didn't \ underflow, then log(A) - log(Q) < 256, so we jump to \ LL2 to return a result of 255 TAX \ Otherwise we return the A-th entry from the antilogODD LDA antilogODD,X \ table STA R \ Set the result in R to the value of A RTS \ Return from the subroutine
Code variation 7 of 8
See variation 4 above for details.
This variation is blank in the Cassette, Disc (flight), Disc (docked), 6502 Second Processor and Electron versions.
\.LL28 \ These instructions are commented out in the original \CMP Q \ source BCS LL2 \ If the subtraction fitted into one byte and didn't \ underflow, then log(A) - log(Q) < 256, so we jump to \ LL2 to return a result of 255 LDX #254 \ Otherwise set the result in R to 254 STX R
.LL31 ASL A \ Shift A to the left BCS LL29 \ If bit 7 of A was set, then jump straight to the \ subtraction CMP Q \ If A < Q, skip the following subtraction BCC P%+4 SBC Q \ A >= Q, so set A = A - Q ROL R \ Rotate the counter in R to the left, and catch the \ result bit into bit 0 (which will be a 0 if we didn't \ do the subtraction, or 1 if we did) BCS LL31 \ If we still have set bits in R, loop back to LL31 to \ do the next iteration of 7 RTS \ R left with remainder of division .LL29 SBC Q \ A >= Q, so set A = A - Q SEC \ Set the C flag to rotate into the result in R ROL R \ Rotate the counter in R to the left, and catch the \ result bit into bit 0 (which will be a 0 if we didn't \ do the subtraction, or 1 if we did) BCS LL31 \ If we still have set bits in R, loop back to LL31 to \ do the next iteration of 7
The advanced versions of LL28 return the remainder in A, which the other versions don't.
This variation is blank in the Cassette, Disc (flight), Disc (docked) and Electron versions.
LDA R \ Set A to the remainder in R
RTS \ Return from the subroutine with R containing the \ remainder of the division .LL2 LDA #255 \ The division is very close to 1, so return the closest STA R \ possible answer to 256, i.e. R = 255 RTS \ Return from the subroutine