Multiplication and division using the hardware registers
Unsigned Multiplication
Registers used: | Accessed by: | Description |
---|---|---|
$4202 | W (Single) | Unsigned multiplicand |
$4203 | W (Single) | Unsigned multiplier, writing here starts multiplication |
$4216 | R (Single) | Low byte of Result |
$4217 | R (Single) | High byte of Result |
After writing your value to $4203
, the multiplication process will start. You will then have to wait for 8 machine cycles (4 NOP
instructions) to retrieve your result from $4216
and $4217
. Of course, you don't need to use 4 NOP
s, you can also do something else, just make sure that at least 8 cycles pass before reading the data. If you read to early, the result will most likely be garbage.
Signed Multiplication
Registers used: | Accessed by: | Description |
---|---|---|
$211B | W (Double) | Signed multiplicand, 16-bits wide |
$211C | W (Single) | Un?signed multiplier, 8-bits |
$2134 | R (Triple) | Signed result, 24-bits, needs to be read three times |
Same as before, writing to the multiplier starts the multiplication process.
- The result can instantly be retrieved from
$2134
$2134
needs to be read three times, 1st time returning the lowest 8 bits, 2nd time the middle, and last the highest 8 bits- !!
$211B
and$211C
can only be used during V-blank when mode 7 is in use.
LDA #$D0 ; Low byte of $8AD0
STA $211B
LDA #$8A ; High byte of $8AD0
STA $211B ; This sets up the multiplicand
LDA #$09 ; $09
STA $211C ; This sets up the multiplier
LDA $2134 ; A = $50 (result low byte)
LDA $2135 ; A = $E1 (result middle byte)
LDA $2136 ; A = $FB (result high byte)
; (= $FBE150)
Unsigned Division
Registers used: | Accessed by: | Description |
---|---|---|
$4204 | W (Single) | Low byte of dividend |
$4205 | W (Single) | High byte of dividend |
$4206 | W (Single) | 8-bit divisor, starts division |
$4214 | R (Single) | Low byte of quotient |
$4215 | R (Single) | High byte of quotient |
$4216 | R (Single) | Low byte of remainder |
$4217 | R (Single) | High byte of remainder |
All the aforementioned values are unsigned.
When the divisor is written to, the division starts. The program will have to wait for 16 cycles (8 NOP
s) before being able to read the results.
LDA #$01
STA $4204
LDA #$01 ; Write $0101 to dividend
STA $4205
LDA #$02 ; Write $02 to the divisor
STA $4206
NOP ; Wait for 16 machine cycles
NOP
NOP
NOP
NOP
NOP
NOP
NOP
LDA $4214 ; A = $80 (result low byte)
LDA $4215 ; A = $00 (result high byte)
LDA $4216 ; A = $01, as there is a remainder (remainder low byte)
LDA $4217 ; A = $00 (remainder high byte)
You can also choose to make a subroutine to do multiplication in the case that $211B
and $211C
are in use because of mode 7. Code for this can be found at 16-bit multiplication and division