B side: Doing arithmetic

B B side · Fortran · The language that speaks maths
How do you tell the machine to calculate?
19 Fortran words in this segment
23 Assembly words for the same job
What Fortran says well here
- You write the formula as maths: v = v + a*dt.
- Fortran has many ready-made maths idioms, for example SQRT, SIN and ATAN2.
- Fortran can do the same whole-number steps as the 8086: SHIFTA keeps the sign in a shift, and IAND cuts a value to one byte. Thus, the laboratory can repeat the A-side arithmetic exactly and compare the answers.
What is hard to say
- On old hardware without a maths chip, decimal-point arithmetic is slow.
- A whole number does not wrap by itself. For the quarter turn, the B side must say modulo(t + 64, 256). MOD is different: mod(-1, 256) is -1, but modulo(-1, 256) is 255.
One sentence in Fortran
speed = speed + boostIt says: The same idea in one sentence.
The words, by part of speech
Idioms (15) · A built-in function or subroutine, for example SQRT or MATMUL.
| Word | Meaning | Example |
|---|---|---|
| SQRT | Square root. | r = sqrt(x**2 + y**2) |
| ABS | The size of a number without its sign. | d = abs(x - y) |
| SIN / COS | Sine and cosine. The angle is in radians. | vx = v*cos(angle) |
| ATAN2 | The angle of a point (y, x). | angle = atan2(y, x) |
| EXP / LOG | The exponential and the natural logarithm. | p = exp(-t/tau) |
| MOD | The remainder after a division. | frame = mod(tick, 4) |
| MAX / MIN | The largest / smallest of the values. | fuel = max(fuel, 0.0) |
| NINT | Round to the nearest whole number. | px = nint(x) |
| FLOOR | Round down to a whole number. | row = floor(y) |
| REAL( ) | Change a whole number into a REAL. | avg = real(total) / n |
| INT( ) | Change a REAL into a whole number. It drops the fraction. | i = int(x) |
| MODULO | The remainder that wraps around, never negative: modulo(-1, 256) is 255. MOD keeps the sign: mod(-1, 256) is -1. A byte register on the A side wraps like MODULO. | z = table(modulo(t + 64, 256)) |
| IAND | Bitwise AND: keep only the bits that are 1 in both numbers. The same job as AND on the A side. | byte = iand(v, 255) |
| ISHFT / SHIFTA | Move the bits of a whole number. SHIFTA moves right and keeps the sign, as SAR does. ISHFT fills with zeros, as SHL and SHR do. | y = shifta(s * 64, 8) |
| RANDOM_NUMBER | Fill a value or an array with random numbers from 0 to 1. The laboratory uses it to make a terrain. | call random_number(r) |
Grammar marks (4) · Maths signs (+ - * / **), the = sign, and (:) for part of an array.
| Word | Meaning | Example |
|---|---|---|
| + - | Add and subtract. | v = v + a*dt |
| * / | Multiply and divide. A division of two whole numbers drops the fraction: 7/2 is 3. | half = total / 2 |
| ** | Raise to a power. x**2 is x times x. | e = 0.5*m*v**2 |
| ( ) | Group a part of a formula, as in maths. | a = (b + c) * d |
Watch out: what the review found
These notes come from the review of the AI-written guides. They show traps that are easy to miss.
- D02-C2 critical The document contradicts itself. Without an FPU, Fortran
REALarithmetic runs on software emulation. The document praises Assembly because it prevents this latency (L41). A Fortran simulation with much float math on a 1980s computer is slow. - D01-M2 major This names the wrong layer. The CPU hardware does out-of-order execution, and the hardware disambiguates memory at runtime. Aliasing (two names for the same memory) limits compiler reordering and vectorization.
- D01-m1 minor "replacement of integer division with modular multiplication invariants". The usual term is multiplication by a fixed-point reciprocal (the "magic number").
- D14-C3 critical The video gives the idea only: from the X and Y of the player, with the scroll, find the tile under the player (05:50). Inkbox says this is "faster" than a loop over a wall list (06:11). He gives no formula, no complexity class and no cycle counts. The formula in image 9 is also wrong. Shift results must be added, not combined with OR: for Y = 3, (3<<7) OR (3<<6) = 448, but 3*192 = 576. The OR between Y*192 and X also fails, for example Y = 1, X = 65 gives 193, not 257. The formula also assumes one byte per tile. The video says that 192 x 168 tiles fill 63 K (06:53), so each tile takes two bytes. The video does not describe timer routines for off-screen enemies. Object collision uses generic hitbox functions against the player (38:55) and against on-screen chickens (42:19).
- D14-M3 major The 5A22 has a hardware unit: $4202 and $4203 start an 8 x 8 unsigned multiply, $4204 to $4206 start a 16 / 8 unsigned divide, and $4214 to $4217 give the quotient, product and remainder (snes.nesdev.org MMIO registers, checked by WebFetch). The video does not give division cost as the reason. Inkbox uses BCD because "it makes the math so much easier" (32:05). The document also omits the trap of the video: INC and DEC ignore the decimal flag, so he must use ADC (32:05 to 32:26). The "LSR and AND" nibble split at L106 is not in the video.