Skip to content

Test 3a: the wave turns

In test 2a, the wave had depth. Here, the wave goes straight from the back to the front, through the center of the 3D space. Then it turns around that center, like a record on a turntable, and the dot moves along it. At a quarter turn, the wave goes from left to right, as intest 1.

A cassette tape with a handwritten label: "A Side. Assembly - the first language of the machine."

A What the machine does

The routines spin_point and project, for the dot on the screen now.

    Waiting for the copy of the PC to start…

    Speed:

    Magenta: the ring, the circle that the two ends of the wave follow. Gray: the wave. Cyan: its footprint on the floor. The wave turns one step for each two steps of the dot. A full turn has 256 steps.

    A cassette tape with a handwritten label: "B Side. Fortran, the language that speaks maths."

    B The maths behind it

    The turn, seen from above, and the same point with decimal-point numbers.

    From above: the wave turns around the center
    backfront

      What is new in test 3a

      1. A A second angle, the turn. Each point of the wave has its place on the wave, d = 128 − angle. Before the turn, the point is at X = 0 and Z = d: the wave goes from the back to the front. After a turn T, the point is at X = d · sin(T) and Z = d · cos(T). The routine isspin_point in src/spin3d.inc.
      2. B The same table again. The cosine of the turn is the sine a quarter turn later. A full turn has 256 steps, so a quarter turn is 64 steps. Thus the A side reads the cosine from sine.bin at T + 64. Test 3b shows what happens with a wrong quarter turn.
      3. A A product that is too large for AX. d · sin(T) can be 128 · 256 = 32768. That number does not fit in AX with a sign. IMUL puts the full product in DX:AX, and the program keeps the middle two bytes: a division by 256.
      4. A Double buffering. In tests 1 and 2, the program drew the curve once. Here, the wave turns, so the whole picture changes at each step. If the program draws on the screen, you see the wave go away and come back. Thus the program keeps two pictures of 64000 bytes in the memory after the program: the background (the floor and the ring, drawn once) and the work buffer. For each step, it copies the background into the work buffer, draws the wave and the dot there, and copies the finished picture to the screen. The 8086 word REP MOVSW copies 32000 words with one instruction. The shared routines for the keys, the pixels and the screen refresh are now in src/common.inc.
      5. A B The check. The test (test/check3r.asm) runs the routines for 16 turns (0, 16, 32 … 240) and all 256 angles: 4096 points. The checker (lab/check_spin.f90) calculates them again and compares them.
      The two sides agree
      4096 / 4096
      points from the check (16 turns × 256)
      Error from exact maths
      1 px
      the cost of whole-number arithmetic
      Size of the game
      1219 bytes
      SPIN3D.COM, 8086 instructions only
      Size of the table
      512 bytes
      the same sine.bin as test 1

      The words that each program uses

      The pills show the words that the dictionary already has. "New words" are real words of the language that the dictionary does not have yet.

      A src/spin3d.asm· 253 lines · The game (test 3a): draws the floor and the ring, and turns the wave with the dot on it

      44 dictionary words: MOVPUSHPOPAXBXCXDXSIDIBPDSESCS[ ]BYTEDBDWADDINCANDXORCMPTESTJMPJE / JZJNE / JNZJB / JACALLRETlabel:REPMOVSWSTOSWCLDORGBITS%includeINCBIN;,hINTINT 10h, AX=0013hA000h

      New words (10): AHALBHBLCHCLCPUDLJGEJLE

      A src/spin3d.inc· 60 lines · The shared routine: one angle along the wave and one turn in, one 3D point out

      20 dictionary words: MOVPUSHPOPAXBXCXSIBP[ ]EQUADDSUBIMULSHLANDRETlabel:;,h

      New words (3): AHALDL

      A src/common.inc· 75 lines · The shared routines of tests 2 and 3: the keys, the pixels and the screen refresh

      33 dictionary words: MOVPUSHPOPAXBXDXDI[ ]BYTEDBXLATADDSUBMULORXORCMPTESTJMPJE / JZJNE / JNZJB / JARETlabel:;,hINTINT 16h, AH=00hINT 16h, AH=01hINT 10h, AX=0003hIN3DAh

      New words (1): AL

      A test/check3r.asm· 68 lines · The test: runs the routines for 16 turns and 256 angles, and writes the positions to a file

      28 dictionary words: MOVPUSHPOPAXBXCXDXSIDIBP[ ]DBEQUADDINCXORCMPJB / JACALLlabel:ORGBITS%includeINCBIN;,hINT

      New words (3): AHCPUJC

      B lab/check_spin.f90· 86 lines · The checker: compares the A-side positions with its own answers

      43 dictionary words: INTEGERREALCHARACTER::=PARAMETERINT8 / INT16REAL64+ -* /( )ABSSIN / COSNINTFLOORINT( )MODULOISHFT / SHIFTAIF ... THEN ... END IFDOSTOPERROR STOPMERGE== /= < > <= >=SUMMAXVAL / MINVALCOUNTANY / ALLPROGRAMENDUSEIMPLICIT NONECALL!&PRINTWRITEREADOPENCLOSEGET_COMMAND_ARGUMENT'(F8.2)'ISO_FORTRAN_ENV

      New words (7): ACOSCOMMAND_ARGUMENT_COUNTDIMINTRINSICLENONLYTRIM

      Next: test 3b runs this program with one wrong value, and shows how it breaks the game and how the check finds it.