A bouncing ball

A ball that turns round at all four edges, drawn off screen and shown a whole frame at a time, paced by the frame port instead of by how fast your machine is.

A ball crosses the screen and turns round at every edge, and a bar along the top grows with the time the program has been running. It never stops on its own: press Run, watch it, and press Stop when you have had enough.

Drawing shapes on the screen drew one picture and stopped. This one draws a new picture forty or fifty times a second, which brings two problems with it: the reader must never see a half drawn frame, and the ball must move at the same speed whatever the machine underneath is doing.

You need to know: the "Drawing shapes on the screen" Example and the "The screen, keyboard and mouse through ports" lecture. What is new here is double buffering, command 11 sends every drawing to an off-screen copy and command 13 shows the whole of it at once.

The frame is four steps and they are always in this order: clear the image, draw everything on it, show it with command 13, and wait for the next frame. Command 9 is the clear, and it wipes text and graphics together, because they are one image. Without command 11 at the top the same four steps would draw straight onto what you are looking at, and you would watch the screen go blue and the ball appear, forty times a second, which is what flicker is.

in a, (P_FRAME) is the pacing. Reading port 0x41 suspends the program until the display's next frame and gives back 0, so one read per pass is what makes the ball move at the same speed on a fast machine and a slow one. It suspends the program without freezing the editor, so Stop still answers and the Screen still repaints, and inside a testcase it returns at once so a test of an animation does not take a minute.

Port 0x42 is the same clock read a different way: it gives one byte of the hundredths of a second since the run started, and b chooses which byte, so ld b, 0 asks for the lowest eight bits. That byte is the width of the bar, and it wraps at 256 all by itself because the Screen is 256 pixels wide and a byte counts exactly that far. The M68K has to divide its clock by 640 to get the same effect.

The ball's position and step are four bytes in memory, because the drawing already uses a for every out, b and c for the time port and e to carry the bar's width across it. ld hl, stepx and add a, (hl) is the step being read where it lies, and the three instructions under the jr c negate it in place, which turns the ball round without either edge knowing which way it was going.

cp LIMITX catches both edges with one unsigned comparison. A step that would take x past 232 fails it the obvious way, and a step that would take x below zero wraps the byte round past 250, which fails it as well. LIMITX equ 256 - SIZE is worked out by the assembler out of the Screen width and the ball, so neither number appears anywhere else.

Try changing SIZE equ 24 to SIZE equ 60. The ball is more than twice as wide and turns round earlier at every edge, because both limits are worked out from that one line.