Division: Difference between revisions
NovaSquirrel (talk | contribs) (Created page with "The 65c816 does not include a division instruction. However, the SNES includes division hardware for games to use, and games can access it with registers. It's capable of dividing a 16-bit number by an 8-bit number, and it produces a 16-bit result and a 16-bit remainder. All inputs and outputs are unsigned. == Division registers == WRDIVH WRDIVL $4205 $4204 7 bit 0 7 bit 0 ---- ---- ---- ---- HHHH HHHH LLLL LLLL |||| |||| |||| |||| +++...") |
NovaSquirrel (talk | contribs) (→Division registers: Right justify the registers to line them up) |
||
Line 11: | Line 11: | ||
++++-++++---++++-++++- Dividend (16-bit unsigned) | ++++-++++---++++-++++- Dividend (16-bit unsigned) | ||
WRDIVB | |||
$4206 | |||
7 bit 0 | |||
---- ---- | |||
NNNN NNNN | |||
|||| |||| | |||
++++-++++- Divisor (8-bit unsigned) | |||
RDDIVH RDDIVL | RDDIVH RDDIVL |
Revision as of 01:59, 21 May 2022
The 65c816 does not include a division instruction. However, the SNES includes division hardware for games to use, and games can access it with registers. It's capable of dividing a 16-bit number by an 8-bit number, and it produces a 16-bit result and a 16-bit remainder. All inputs and outputs are unsigned.
Division registers
WRDIVH WRDIVL $4205 $4204 7 bit 0 7 bit 0 ---- ---- ---- ---- HHHH HHHH LLLL LLLL |||| |||| |||| |||| ++++-++++---++++-++++- Dividend (16-bit unsigned) WRDIVB $4206 7 bit 0 ---- ---- NNNN NNNN |||| |||| ++++-++++- Divisor (8-bit unsigned) RDDIVH RDDIVL $4215 $4214 7 bit 0 7 bit 0 ---- ---- ---- ---- HHHH HHHH LLLL LLLL |||| |||| |||| |||| ++++-++++---++++-++++- Division result (16-bit unsigned) RDMPYH RDMPYL $4217 $4216 7 bit 0 7 bit 0 ---- ---- ---- ---- HHHH HHHH LLLL LLLL |||| |||| |||| |||| ++++-++++---++++-++++- Division remainder (16-bit unsigned)
Writing to WRDIVB
starts the division process. The division process takes 16 CPU clock cycles before it's finished (regardless of if those clock cycles are 2.68MHz or 3.58MHz). Reading the result registers before division has completed will return intermediate results.
The time spent reading the instruction that reads the result counts toward the wait. For instance, if the registers are read with LDA absolute
, that instruction will spend 3 cycles before reading the result, and LDA long
will spend 4 cycles before reading the result. This means the program only effectively needs to wait 12 or 13 cycles. A program can simply wait the required time with NOP
(2 cycles each instruction) but ideally that time is spent doing something else the program needs to do, like preparing registers or flags for something it intends to do with the division result.
Division by zero will produce a result of $FFFF, and a remainder that is equal to the dividend.
References
- 16-bit multiplication and division - Example of using the divider to do divisions with bigger numbers