Lander starts a flight where a flight starts
run does not reload, and that is right: run's job is to run the program that is loaded, which is why it is a separate word from load and why typing a program's name does both. What follows is that the numbers the assembler wrote into a Data Segment are LOAD-time values, true once, and a program that wants them true at every start has to say so itself. Lander did not. Flying is 0x01 in the data and is only ever cleared, so a second run began with the loop already over: the program started and handed the machine straight back. Reproduced by running it, quitting, and running again - the leftover game keys land at the shell prompt, which is what a program that never read them looks like. AND THE TEST FOUND A SECOND ONE, quieter and worse. The terrain seed is a written number, so a fresh load always walks out the same moon - but nextRandom moves it, and a second run generated a DIFFERENT moon. Nobody decided that. A test comparing the whole screen found it without anybody having had to think of it in advance, which is the argument for comparing the picture rather than the variables somebody remembered to check. Only what a flight needs to begin is put back. Anything not on the list keeps what the last run left it, which is deliberate - state surviving a run is sometimes exactly what is wanted, and the way to have that is for the list to be a decision rather than a sweep. The things that are simply nought are a table of NAMES that the assembler turns into addresses, so adding a variable that must start empty means adding it there and nowhere else. video.sh now runs Lander, quits, runs it again, and requires the same picture a hundred frames in - the same moon, the same lander in the same place, the same gauges. break.sh confirms it by taking the seed line back out: 37,995 bytes of the picture differ. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
b160c66110
commit
87467a7d3a
@@ -25,7 +25,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 9201
|
||||
Lander.sbx 9361
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -15,7 +15,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 9201
|
||||
Lander.sbx 9361
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -32,7 +32,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 9201
|
||||
Lander.sbx 9361
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 9201
|
||||
Lander.sbx 9361
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 9201
|
||||
Lander.sbx 9361
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -108,7 +108,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 9201
|
||||
Lander.sbx 9361
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -27,7 +27,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 9201
|
||||
Lander.sbx 9361
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -15,7 +15,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 9201
|
||||
Lander.sbx 9361
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -13,7 +13,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 9201
|
||||
Lander.sbx 9361
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 9201
|
||||
Lander.sbx 9361
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -3249,6 +3249,44 @@ PY2
|
||||
)"
|
||||
[ "$LETTERS" = "16" ] && result ok "and does not rub out what it moves over" "all sixteen letters are still there" || result no "and does not rub out what it moves over" "$LETTERS of sixteen cells still have ink"
|
||||
|
||||
# ---- Running a program twice is the same as running it once ----
|
||||
#
|
||||
# RUN DOES NOT RELOAD, and that is right: run's job is to run the program that is loaded,
|
||||
# which is why it is a separate word from load and why typing a program's name does both. It
|
||||
# follows that the numbers the assembler wrote into a Data Segment are LOAD-time values, true
|
||||
# once - and a program that wants them true at every start has to say so itself.
|
||||
#
|
||||
# Lander did not. A second run began with Flying already nought, so the loop ended before it
|
||||
# started and the program handed the machine straight back. Worse and quieter: the terrain
|
||||
# seed is a written number, so a fresh load always walks out the same moon - but nextRandom
|
||||
# moves it, and a second run generated a different moon, which was nobody's decision.
|
||||
#
|
||||
# THE CHECK IS THE WHOLE SCREEN, because that is the only thing that knows about all of it at
|
||||
# once. A hundred frames in, run once and run twice have to be the same picture: the same
|
||||
# moon, the same lander in the same place, the same gauges. Any state that survives a run and
|
||||
# should not shows up here without anybody having to have thought of it in advance.
|
||||
python3 -c "
|
||||
open('$BUILD/once.keys','wb').write(b'Lander\n' + b'\x00'*100)
|
||||
open('$BUILD/twice.keys','wb').write(b'Lander\n' + b'\x00'*100 + b'q' + b'\x00'*20 + b'run\n' + b'\x00'*100)
|
||||
open('$BUILD/still.pad','wb').write(b'\x00' * 20000)"
|
||||
for WHEN in once twice; do
|
||||
timeout 60 "$EMU" --fast --cycles 24000000 --keyboard "$BUILD/$WHEN.keys" \
|
||||
--pad "$BUILD/still.pad" --screen "$BUILD/run$WHEN.ppm" \
|
||||
--disk "$ROOT/Tests/build/disks/cosmos.img" --ram-disk 2048 \
|
||||
"$BUILD/cosmos.bin" > "$BUILD/run$WHEN.out" 2>&1 || true
|
||||
done
|
||||
if [ ! -f "$BUILD/runonce.ppm" ] || [ ! -f "$BUILD/runtwice.ppm" ]; then
|
||||
result no "a program run twice starts where it started" "no picture came out"
|
||||
elif cmp -s "$BUILD/runonce.ppm" "$BUILD/runtwice.ppm"; then
|
||||
result ok "a program run twice starts where it started" "the same screen a hundred frames in"
|
||||
else
|
||||
DIFFERS="$(python3 -c "
|
||||
a = open('$BUILD/runonce.ppm','rb').read()
|
||||
b = open('$BUILD/runtwice.ppm','rb').read()
|
||||
print(sum(1 for x, y in zip(a, b) if x != y))")"
|
||||
result no "a program run twice starts where it started" "$DIFFERS bytes of the picture differ"
|
||||
fi
|
||||
|
||||
echo
|
||||
if [ "$FAIL" -eq 0 ]; then
|
||||
echo "All $PASS video checks passed."
|
||||
|
||||
Reference in New Issue
Block a user