diff --git a/Programs/CosmOS/Apps/Lander.asm b/Programs/CosmOS/Apps/Lander.asm index 1018afb..3caceb8 100644 --- a/Programs/CosmOS/Apps/Lander.asm +++ b/Programs/CosmOS/Apps/Lander.asm @@ -371,11 +371,30 @@ burnRight: CALL addWord RET -; Gravity, which is the same small number every frame and the reason this is a game. +; ---- Gravity, which is the reason this is a game ---- +; +; NOT EVERY FRAME. One sixteenth of a pixel per frame per frame is the smallest step this +; arithmetic can take and it is still far too much - it crossed the screen in a second and +; flew like a gas giant. So it is applied one frame in FallEvery, which divides the pull by +; that much and costs a byte and a compare. +; +; The alternative was a finer unit for velocity than for position, which means a shift every +; time one is added to the other, twice a frame, for ever. A counter is cheaper and it is one +; byte to change while the feel is being found. fall: + SETD.1 FallTick + LDA.1 + DECA + STA.1 + BNA fallDone + SETD.1 FallEvery + LDA.1 + SETD.1 FallTick + STA.1 SETD.0 SpeedDown SETD.1 Gravity CALL addWord +fallDone: RET ; ---- Where it is now ---- @@ -425,7 +444,7 @@ follow: SETD.0 PixelLow LDB.0 CALL eighth - OUTA 0x36 ; The column origin. + OUTQ 0x36 ; The column origin. IN Q, because RET puts A back. RET ; ---- The lander, put where it now is ---- @@ -514,7 +533,16 @@ toPixels: ; Three turns right is a divide by eight, and a moon 1024 pixels round is 128 columns, so the ; whole answer is in the low half and the high half is the bits that rotated out of it. ; -; B cannot be read. Adding nothing to it puts it in Q, which can be moved. +; ---- And the answer comes back in Q ---- +; +; It came back in A first, which is a lie a subroutine cannot tell: RET puts A back the way it +; found it, so the caller wrote out the high byte of the position it had passed in. The fine +; register was computed inline and was right, the coarse register was not, and the picture +; scrolled smoothly within a cell and never advanced one. Q is the only register that crosses +; a RET, which is why every answer in this program comes back in it. +; +; B cannot be read at all. Adding nothing to it puts it in Q, which is where this wanted to +; be anyway. eighth: SHR SHR @@ -522,7 +550,6 @@ eighth: RSTA CCF ADD - MVQA RET waitFrame: @@ -550,14 +577,21 @@ SpeedAcross: SpeedDown: 0x00 0x00 +; ---- The four numbers the feel lives in ---- +; +; Adjacent on purpose, because tuning them is what the first rung is for. Gravity: 0x01 0x00 +FallEvery: + 0d6 ; Gravity one frame in six. Every frame was Jupiter. +FallTick: + 0d1 ThrustUp: - 0xEC 0xFF ; Twenty sixteenths upwards, which is minus twenty. + 0xF8 0xFF ; Eight sixteenths upwards, which is minus eight. ThrustLeft: - 0xF8 0xFF ; Eight sixteenths to the left. + 0xFC 0xFF ; Four to the left. ThrustRight: - 0x08 0x00 + 0x04 0x00 HalfScreen: 0xA0 0x00 ; 160 pixels, which is half of a forty column screen. diff --git a/Tests/expected/cosmosCrossDisk.out b/Tests/expected/cosmosCrossDisk.out index 25d337b..3ba506e 100644 --- a/Tests/expected/cosmosCrossDisk.out +++ b/Tests/expected/cosmosCrossDisk.out @@ -25,7 +25,7 @@ Mode.sbx 48 Flip.sbx 173 Sprite.sbx 442 Depth.sbx 672 -Lander.sbx 984 +Lander.sbx 1009 Crash.sbx 632 vars.script 50 blocks.script 343 diff --git a/Tests/expected/cosmosDrives.out b/Tests/expected/cosmosDrives.out index 290c7fd..70605e4 100644 --- a/Tests/expected/cosmosDrives.out +++ b/Tests/expected/cosmosDrives.out @@ -15,7 +15,7 @@ Mode.sbx 48 Flip.sbx 173 Sprite.sbx 442 Depth.sbx 672 -Lander.sbx 984 +Lander.sbx 1009 Crash.sbx 632 vars.script 50 blocks.script 343 diff --git a/Tests/expected/cosmosFault.out b/Tests/expected/cosmosFault.out index 865706a..c9ae451 100644 --- a/Tests/expected/cosmosFault.out +++ b/Tests/expected/cosmosFault.out @@ -32,7 +32,7 @@ Mode.sbx 48 Flip.sbx 173 Sprite.sbx 442 Depth.sbx 672 -Lander.sbx 984 +Lander.sbx 1009 Crash.sbx 632 vars.script 50 blocks.script 343 diff --git a/Tests/expected/cosmosFlip.out b/Tests/expected/cosmosFlip.out index 1ef4ce8..d39e2ef 100644 --- a/Tests/expected/cosmosFlip.out +++ b/Tests/expected/cosmosFlip.out @@ -22,7 +22,7 @@ Mode.sbx 48 Flip.sbx 173 Sprite.sbx 442 Depth.sbx 672 -Lander.sbx 984 +Lander.sbx 1009 Crash.sbx 632 vars.script 50 blocks.script 343 diff --git a/Tests/expected/cosmosGrid.out b/Tests/expected/cosmosGrid.out index d2e08f5..76487b9 100644 --- a/Tests/expected/cosmosGrid.out +++ b/Tests/expected/cosmosGrid.out @@ -22,7 +22,7 @@ Mode.sbx 48 Flip.sbx 173 Sprite.sbx 442 Depth.sbx 672 -Lander.sbx 984 +Lander.sbx 1009 Crash.sbx 632 vars.script 50 blocks.script 343 diff --git a/Tests/expected/cosmosMonitor.out b/Tests/expected/cosmosMonitor.out index 9cb4e64..e977938 100644 --- a/Tests/expected/cosmosMonitor.out +++ b/Tests/expected/cosmosMonitor.out @@ -108,7 +108,7 @@ Mode.sbx 48 Flip.sbx 173 Sprite.sbx 442 Depth.sbx 672 -Lander.sbx 984 +Lander.sbx 1009 Crash.sbx 632 vars.script 50 blocks.script 343 diff --git a/Tests/expected/cosmosMonitorRun.out b/Tests/expected/cosmosMonitorRun.out index e4e7410..2dfb143 100644 --- a/Tests/expected/cosmosMonitorRun.out +++ b/Tests/expected/cosmosMonitorRun.out @@ -27,7 +27,7 @@ Mode.sbx 48 Flip.sbx 173 Sprite.sbx 442 Depth.sbx 672 -Lander.sbx 984 +Lander.sbx 1009 Crash.sbx 632 vars.script 50 blocks.script 343 diff --git a/Tests/expected/cosmosRun.out b/Tests/expected/cosmosRun.out index 6f7af5c..8278c93 100644 --- a/Tests/expected/cosmosRun.out +++ b/Tests/expected/cosmosRun.out @@ -15,7 +15,7 @@ Mode.sbx 48 Flip.sbx 173 Sprite.sbx 442 Depth.sbx 672 -Lander.sbx 984 +Lander.sbx 1009 Crash.sbx 632 vars.script 50 blocks.script 343 diff --git a/Tests/expected/cosmosSlowDisk.out b/Tests/expected/cosmosSlowDisk.out index 3ef56f5..39633d7 100644 --- a/Tests/expected/cosmosSlowDisk.out +++ b/Tests/expected/cosmosSlowDisk.out @@ -13,7 +13,7 @@ Mode.sbx 48 Flip.sbx 173 Sprite.sbx 442 Depth.sbx 672 -Lander.sbx 984 +Lander.sbx 1009 Crash.sbx 632 vars.script 50 blocks.script 343 diff --git a/Tests/expected/cosmosSprite.out b/Tests/expected/cosmosSprite.out index c580f52..ce25fac 100644 --- a/Tests/expected/cosmosSprite.out +++ b/Tests/expected/cosmosSprite.out @@ -22,7 +22,7 @@ Mode.sbx 48 Flip.sbx 173 Sprite.sbx 442 Depth.sbx 672 -Lander.sbx 984 +Lander.sbx 1009 Crash.sbx 632 vars.script 50 blocks.script 343 diff --git a/Tests/video.sh b/Tests/video.sh index 977e904..fe471e3 100755 --- a/Tests/video.sh +++ b/Tests/video.sh @@ -1525,17 +1525,23 @@ EOT # takes the screen, changes the mode, redefines tiles, fills all 3,200 cells of the map from a # terrain it generated, and moves a sprite over it every frame. # -# The keys are a burn of the lifting thruster every sixteenth frame, which is more than the -# gravity and so keeps the lander up long enough to be looked at. The cycle count is tuned to -# catch it before it climbs off the top; if CosmOS's size shifts the boot far enough, the -# lander check fails saying it is not on screen, which is a request to re-tune. +# A burn of the lifting thruster every forty eighth frame, which is exactly the gravity: one +# sixteenth of a pixel every sixth frame against eight every forty eighth. Exactly cancelling +# the ACCELERATION still leaves an average velocity, so it drifts upward slowly and this is +# caught early rather than left to settle. +# +# EARLY, and that is the point of 1.5 million cycles. This program starts almost at once - the +# first guess at where to look was ten million cycles in, on the assumption that taking a +# screen was expensive, and by then the lander had flown 700 frames and left the picture. A +# capture near the start is worth far more than a tuned one: there is much less between it and +# the beginning that can move. python3 -c " keys = b'Lander\n' for i in range(400): - keys += b'\x80' + b'\x00' * 15 -open('$BUILD/lander.keys','wb').write(keys + b'\x00' * 4000) + keys += b'\x80' + b'\x00' * 47 +open('$BUILD/lander.keys','wb').write(keys + b'\x00' * 8000) " -timeout 30 "$EMU" --fast --cycles 12000000 --keyboard "$BUILD/lander.keys" \ +timeout 30 "$EMU" --fast --cycles 1500000 --keyboard "$BUILD/lander.keys" \ --screen "$BUILD/lander.ppm" --disk "$ROOT/Tests/build/disks/cosmos.img" \ --ram-disk 2048 "$BUILD/cosmos.bin" > "$BUILD/lander.out" 2>&1 || true read -r MOON SKY SHIP SHIPLEFT SHIPRIGHT <