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 NOPs, 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 NOPs) 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