A base speaks in the window, not into the world
Two bugs with one cause. The console draws into the map, so a message printed while flying was a message the lander then flew over - and printing scrolls, so every one of them moved the whole world up a row. The window is at a screen position and forty cells wide, and neither is true of it. So the window is two rows now: the gauge, and whatever there is to say. The letters are ordinary tiles, because the character generator starts at the space and glyph n is character n less thirty two. The rest of the row is blanked after every message, or a short one would leave the tail of a long one behind it. Opening the throttle wipes the line, because a message that outlived the moment would be read as describing this one. The crash still goes to the console, deliberately: it is the last thing the program says and it should survive the program. A or Start continues from a message as readily as a key does. Somebody flying on a controller should not have to reach for the keyboard to say they have read something. AND TWO TESTS WENT WITH IT, which is the interesting part. cosmosLanderSoft and cosmosLanderPadOne asserted on lines in a transcript, and the lines moved off the console - so both went on passing while checking nothing at all. A test that asserts a side effect rather than the thing itself is always one refactor from being decorative. What they were for is now checked in the picture, where the message actually is. The lander check moved earlier too. The window grew to two rows, so by 1.5 million cycles the lander had climbed behind the status bar - the window doing exactly what it should, and leaving the check counting six pixels of a forty pixel lander. 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
bfb515e23b
commit
caf5e1f99d
@@ -457,8 +457,8 @@ putLander:
|
|||||||
; The letters are ordinary tiles. The character generator starts at the space, so glyph n is
|
; The letters are ordinary tiles. The character generator starts at the space, so glyph n is
|
||||||
; character n plus thirty two - which makes F, U, E and L into 38, 53, 37 and 44.
|
; character n plus thirty two - which makes F, U, E and L into 38, 53, 37 and 44.
|
||||||
putGauge:
|
putGauge:
|
||||||
INIA 0x01
|
INIA 0x02
|
||||||
OUTA 0x3D ; One row tall.
|
OUTA 0x3D ; Two rows: the gauge, and whatever there is to say.
|
||||||
RSTA
|
RSTA
|
||||||
OUTA 0x3E ; At the top of the screen.
|
OUTA 0x3E ; At the top of the screen.
|
||||||
|
|
||||||
@@ -680,9 +680,14 @@ fallResting:
|
|||||||
BRQ fallNotUp
|
BRQ fallNotUp
|
||||||
CALL takeFuel
|
CALL takeFuel
|
||||||
BRQ fallNotUp ; Nothing in the tank, so nothing out of the engine.
|
BRQ fallNotUp ; Nothing in the tank, so nothing out of the engine.
|
||||||
RSTA
|
|
||||||
SETD.0 Landed
|
SETD.0 Landed
|
||||||
|
LDA.0
|
||||||
|
BRA fallAlreadyUp
|
||||||
|
RSTA
|
||||||
STA.0 ; Lifting off, which is the only way to stop being landed.
|
STA.0 ; Lifting off, which is the only way to stop being landed.
|
||||||
|
SETD.0 EmptyText
|
||||||
|
CALL sayInWindow ; And whatever the base said goes with it.
|
||||||
|
fallAlreadyUp:
|
||||||
SETD.0 SpeedDown
|
SETD.0 SpeedDown
|
||||||
SETD.1 PadUp
|
SETD.1 PadUp
|
||||||
CALL addWord
|
CALL addWord
|
||||||
@@ -1103,13 +1108,24 @@ touchdownStop:
|
|||||||
touchdownDone:
|
touchdownDone:
|
||||||
RET
|
RET
|
||||||
|
|
||||||
; A key, asked for rather than waited on, so one already pressed counts.
|
; ---- A key, or a button ----
|
||||||
|
;
|
||||||
|
; Somebody flying on a controller should not have to reach for the keyboard to say "yes, I
|
||||||
|
; read that". A or Start does it, and so does any key - asked for rather than waited on, so
|
||||||
|
; one already pressed counts.
|
||||||
waitKey:
|
waitKey:
|
||||||
|
CALL readPad
|
||||||
|
SETD.0 Held
|
||||||
|
LDA.0
|
||||||
|
INIB 0x50 ; A, or Start.
|
||||||
|
AND
|
||||||
|
BNQ waitKeyDone
|
||||||
INA 0x01
|
INA 0x01
|
||||||
INIB 0x01 ; READY
|
INIB 0x01 ; READY
|
||||||
AND
|
AND
|
||||||
BRQ waitKey
|
BRQ waitKey
|
||||||
INA 0x00
|
INA 0x00
|
||||||
|
waitKeyDone:
|
||||||
RET
|
RET
|
||||||
|
|
||||||
; ---- Put down exactly on the ground ----
|
; ---- Put down exactly on the ground ----
|
||||||
@@ -1140,6 +1156,53 @@ restOnSurface:
|
|||||||
STA.0
|
STA.0
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
; ---- A line of text, into the window ----
|
||||||
|
;
|
||||||
|
; DP0 names a string. It goes into window row one and the rest of the row is BLANKED, so a
|
||||||
|
; short message never leaves the tail of a long one behind it.
|
||||||
|
;
|
||||||
|
; Into the window rather than out of the console, which is the whole of two bugs at once. The
|
||||||
|
; console draws into the map, so a message printed while flying was a message the lander then
|
||||||
|
; flew over - and printing scrolls, so every one of them moved the whole world up a row.
|
||||||
|
; The window is at a screen position and forty cells wide, and neither is true of it.
|
||||||
|
;
|
||||||
|
; The letters are ordinary tiles: the character generator starts at the space, so glyph n is
|
||||||
|
; character n less thirty two.
|
||||||
|
sayInWindow:
|
||||||
|
INIA 0d5
|
||||||
|
OUTA 0xE3
|
||||||
|
INIA 0xC1
|
||||||
|
OUTA 0xE4
|
||||||
|
RSTA
|
||||||
|
OUTA 0xE5 ; Window row one begins at 0xC100.
|
||||||
|
SETD.1 SayAt
|
||||||
|
STA.1
|
||||||
|
|
||||||
|
sayCell:
|
||||||
|
LDA.0
|
||||||
|
BRA sayBlank ; The string has ended, so the rest of the row is nothing.
|
||||||
|
INIB 0d32
|
||||||
|
CCF
|
||||||
|
SUB
|
||||||
|
OUTQ 0xE9
|
||||||
|
INIA 0x07
|
||||||
|
OUTA 0xE9 ; Scheme seven, white, which is nothing else on this screen.
|
||||||
|
INCD.0
|
||||||
|
BRI sayNext
|
||||||
|
sayBlank:
|
||||||
|
OUTA 0xE9
|
||||||
|
OUTA 0xE9 ; A is nought here, and DP0 stays put so it stays nought.
|
||||||
|
sayNext:
|
||||||
|
SETD.1 SayAt
|
||||||
|
LDA.1
|
||||||
|
INCA
|
||||||
|
STA.1
|
||||||
|
INIB 0d40
|
||||||
|
CCF
|
||||||
|
SUB
|
||||||
|
BNQ sayCell
|
||||||
|
RET
|
||||||
|
|
||||||
; ---- What a base does when a lander arrives ----
|
; ---- What a base does when a lander arrives ----
|
||||||
;
|
;
|
||||||
; Empty and at a base: it hands over cargo for the base ACROSS THE MOON, two along, so the
|
; Empty and at a base: it hands over cargo for the base ACROSS THE MOON, two along, so the
|
||||||
@@ -1172,8 +1235,8 @@ arrive:
|
|||||||
STA.0 ; And DP0 is still Carrying, from reading it.
|
STA.0 ; And DP0 is still Carrying, from reading it.
|
||||||
CALL payFuel
|
CALL payFuel
|
||||||
SETD.0 DeliveredText
|
SETD.0 DeliveredText
|
||||||
SWI osPrintString
|
CALL sayInWindow
|
||||||
BRI arriveSaid
|
RET
|
||||||
|
|
||||||
arriveLoad:
|
arriveLoad:
|
||||||
; Two along, round a moon of four bases, which is the far side of it.
|
; Two along, round a moon of four bases, which is the far side of it.
|
||||||
@@ -1190,21 +1253,17 @@ arriveLoad:
|
|||||||
SETD.0 Carrying
|
SETD.0 Carrying
|
||||||
STA.0
|
STA.0
|
||||||
SETD.0 LoadedText
|
SETD.0 LoadedText
|
||||||
SWI osPrintString
|
CALL sayInWindow
|
||||||
BRI arriveSaid
|
RET
|
||||||
|
|
||||||
arriveWrong:
|
arriveWrong:
|
||||||
SETD.0 WrongText
|
SETD.0 WrongText
|
||||||
SWI osPrintString
|
CALL sayInWindow
|
||||||
BRI arriveSaid
|
RET
|
||||||
|
|
||||||
arriveNowhere:
|
arriveNowhere:
|
||||||
SETD.0 LandedText
|
SETD.0 LandedText
|
||||||
SWI osPrintString
|
CALL sayInWindow
|
||||||
|
|
||||||
arriveSaid:
|
|
||||||
INIA 0x0A
|
|
||||||
OUTA 0x00
|
|
||||||
RET
|
RET
|
||||||
|
|
||||||
; ---- Paid ----
|
; ---- Paid ----
|
||||||
@@ -1475,6 +1534,8 @@ LandColumn:
|
|||||||
0x00
|
0x00
|
||||||
AtBase:
|
AtBase:
|
||||||
0x00
|
0x00
|
||||||
|
SayAt:
|
||||||
|
0x00
|
||||||
|
|
||||||
; ---- What is aboard, and whether the feet are down ----
|
; ---- What is aboard, and whether the feet are down ----
|
||||||
;
|
;
|
||||||
@@ -1486,14 +1547,17 @@ Carrying:
|
|||||||
Landed:
|
Landed:
|
||||||
0x00
|
0x00
|
||||||
|
|
||||||
|
; ---- Forty cells is the row, so forty characters is the limit ----
|
||||||
LandedText:
|
LandedText:
|
||||||
"Down in the middle of nowhere. Nothing here."
|
"Nowhere in particular. Nothing here."
|
||||||
LoadedText:
|
LoadedText:
|
||||||
"Loaded. Take it to the base across the moon."
|
"Loaded. Take it across the moon."
|
||||||
DeliveredText:
|
DeliveredText:
|
||||||
"Delivered. Eighty units of fuel."
|
"Delivered. Eighty units of fuel."
|
||||||
WrongText:
|
WrongText:
|
||||||
"Not the base this cargo is for."
|
"Not the base this cargo is for."
|
||||||
|
EmptyText:
|
||||||
|
0x00
|
||||||
CrashedText:
|
CrashedText:
|
||||||
"Crashed."
|
"Crashed."
|
||||||
|
|
||||||
|
|||||||
@@ -727,7 +727,7 @@ from every assembly file in it. Several are old programs written for the bare ma
|
|||||||
| Grid | The first program to use the screen as a screen. Redefines a tile above the font, fills all 128 map rows, and scrolls it diagonally a pixel at a time. |
|
| Grid | The first program to use the screen as a screen. Redefines a tile above the font, fills all 128 map rows, and scrolls it diagonally a pixel at a time. |
|
||||||
| Sprite | Moves a ball across the shell's own text, writing not one byte of the map to do it. It leaves the sprite in the table on the way out, because clearing them is the system's job - see below. |
|
| Sprite | Moves a ball across the shell's own text, writing not one byte of the map to do it. It leaves the sprite in the table on the way out, because clearing them is the system's job - see below. |
|
||||||
| Pad | Says what the controllers are doing, printing a line whenever one changes. It tells apart the three things that look identical from inside a game that is not responding: a pad nobody noticed, a pad mapped to nothing, and a mapping that is wrong. |
|
| Pad | Says what the controllers are doing, printing a line whenever one changes. It tells apart the three things that look identical from inside a game that is not responding: a pad nobody noticed, a pad mapped to nothing, and a mapping that is wrong. |
|
||||||
| Lander | Lunar Porter, rung one: a lander over a moon that wraps. Flown with a controller if there is one - a held thruster burns every tick it is held for - and with the arrow keys if there is not, where one press is one burn and that is the most the console can say. A bar at the bottom is the sideways drift, drawn as a sprite stretched to the speed - a moon has no air, so a drift never stops by itself and stopping one means cancelling it exactly, which is hard to do blind. It lands or crashes on arrival, and what decides is the speed at the moment it touches: gentler than three quarters of a pixel a frame downwards and half of one sideways, or it is a lander on its side. A fuel gauge sits in the window layer, where the moon turning underneath cannot scroll it away, and every thruster costs a unit of fuel every tick it fires. An empty tank is not an ending: it is a lander still flying that can no longer do anything about where. Four landing pads are carved into the moon after it is generated, levelled to whatever height their first column happened to have, and marked in cyan by an attribute rather than a tile of their own. The lander starts above one, because that is where a porter's day begins. Each pad is a base, told apart by the colour it is drawn in, and landing at one either loads cargo for the base across the moon or delivers what is aboard and pays eighty units of fuel. A landing is not an ending: the lander rests where it is until the throttle opens again. |
|
| Lander | Lunar Porter, rung one: a lander over a moon that wraps. Flown with a controller if there is one - a held thruster burns every tick it is held for - and with the arrow keys if there is not, where one press is one burn and that is the most the console can say. A bar at the bottom is the sideways drift, drawn as a sprite stretched to the speed - a moon has no air, so a drift never stops by itself and stopping one means cancelling it exactly, which is hard to do blind. It lands or crashes on arrival, and what decides is the speed at the moment it touches: gentler than three quarters of a pixel a frame downwards and half of one sideways, or it is a lander on its side. A fuel gauge sits in the window layer, where the moon turning underneath cannot scroll it away, and every thruster costs a unit of fuel every tick it fires. An empty tank is not an ending: it is a lander still flying that can no longer do anything about where. Four landing pads are carved into the moon after it is generated, levelled to whatever height their first column happened to have, and marked in cyan by an attribute rather than a tile of their own. The lander starts above one, because that is where a porter's day begins. Each pad is a base, told apart by the colour it is drawn in, and landing at one either loads cargo for the base across the moon or delivers what is aboard and pays eighty units of fuel. A landing is not an ending: the lander rests where it is until the throttle opens again, and A or Start says "read it" as readily as a key does. What a base says goes in the window rather than out of the console: the console draws into the map, so a message printed while flying is one the lander then flies over, and printing scrolls the whole world up a row. Opening the throttle wipes the line. |
|
||||||
| Depth | Four pillars at four distances and a ball walking past them, behind the near ones and in front of the far ones. The ball is sprite nought and every pillar is numbered after it, so table order puts it in front of all four - what actually decides is the depth buffer, asked a column at a time. |
|
| Depth | Four pillars at four distances and a ball walking past them, behind the near ones and in front of the far ones. The ball is sprite nought and every pillar is numbered after it, so table order puts it in front of all four - what actually decides is the depth buffer, asked a column at a time. |
|
||||||
| Flip | Draws a whole screen into the bank that is not being shown, waits, and then shows it in one byte out of one port. It writes nothing else at all - not a tile, not a colour - so it does not ask for the screen to be saved, and the line it printed is still there when it comes back. It deliberately does not put the displayed screen back either, because that is the system's to restore: a program that faulted while flipped could not have. |
|
| Flip | Draws a whole screen into the bank that is not being shown, waits, and then shows it in one byte out of one port. It writes nothing else at all - not a tile, not a colour - so it does not ask for the screen to be saved, and the line it printed is still there when it comes back. It deliberately does not put the displayed screen back either, because that is the system's to restore: a program that faulted while flipped could not have. |
|
||||||
| Edit | A line editor. |
|
| Edit | A line editor. |
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ from `make`, not from here.
|
|||||||
### 1. Recorded output
|
### 1. Recorded output
|
||||||
|
|
||||||
`Tests/run.sh` assembles each program named in `Tests/manifest`, runs it, and compares
|
`Tests/run.sh` assembles each program named in `Tests/manifest`, runs it, and compares
|
||||||
everything it printed against a file in `Tests/expected`. 212 tests, of which 150 run, 35
|
everything it printed against a file in `Tests/expected`. 210 tests, of which 148 run, 35
|
||||||
only assemble, 16 are expected to fail to assemble, and 11 boot from ROM with no image
|
only assemble, 16 are expected to fail to assemble, and 11 boot from ROM with no image
|
||||||
given at all.
|
given at all.
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 2429
|
Lander.sbx 2490
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 2429
|
Lander.sbx 2490
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 2429
|
Lander.sbx 2490
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 2429
|
Lander.sbx 2490
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 2429
|
Lander.sbx 2490
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
CosmOS
|
|
||||||
> Lander
|
|
||||||
Loaded. Take it to the base across the moon.
|
|
||||||
Not the base this cargo is for.
|
|
||||||
Not the base this cargo is for.
|
|
||||||
Execution stopped. (cycle limit reached)
|
|
||||||
[exit 0]
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
CosmOS
|
|
||||||
> Lander
|
|
||||||
Loaded. Take it to the base across the moon.
|
|
||||||
Not the base this cargo is for.
|
|
||||||
Not the base this cargo is for.
|
|
||||||
Execution stopped. (cycle limit reached)
|
|
||||||
[exit 0]
|
|
||||||
@@ -108,7 +108,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 2429
|
Lander.sbx 2490
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 2429
|
Lander.sbx 2490
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 2429
|
Lander.sbx 2490
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 2429
|
Lander.sbx 2490
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 2429
|
Lander.sbx 2490
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -1027,7 +1027,6 @@ padTest | testPrograms/padTest.asm | run | -
|
|||||||
# speed has no limit and nothing slows it, so a slide always ends badly however the rest is
|
# speed has no limit and nothing slows it, so a slide always ends badly however the rest is
|
||||||
# tuned.
|
# tuned.
|
||||||
cosmosLanderCrash | CosmOS/Source/cosmos.asm | run | - | 60000000 | disks/cosmos.img | lander.keys | landerSlide.pad
|
cosmosLanderCrash | CosmOS/Source/cosmos.asm | run | - | 60000000 | disks/cosmos.img | lander.keys | landerSlide.pad
|
||||||
cosmosLanderSoft | CosmOS/Source/cosmos.asm | run | - | 60000000 | disks/cosmos.img | lander.keys | landerSoft.pad
|
|
||||||
# ---- And the same landing, flown from the second controller ----
|
# ---- And the same landing, flown from the second controller ----
|
||||||
#
|
#
|
||||||
# Two pad fixtures, comma separated: the first holds nothing and the second is the recording
|
# Two pad fixtures, comma separated: the first holds nothing and the second is the recording
|
||||||
@@ -1037,7 +1036,6 @@ cosmosLanderSoft | CosmOS/Source/cosmos.asm | run | -
|
|||||||
# Which is not hypothetical - it is what this did. A controller does not always arrive on
|
# Which is not hypothetical - it is what this did. A controller does not always arrive on
|
||||||
# nought; the front end hands out the numbers the host gave it, so reading only the first
|
# nought; the front end hands out the numbers the host gave it, so reading only the first
|
||||||
# works on the machine it was written on and silently does nothing on the next one.
|
# works on the machine it was written on and silently does nothing on the next one.
|
||||||
cosmosLanderPadOne | CosmOS/Source/cosmos.asm | run | - | 60000000 | disks/cosmos.img | lander.keys | landerIdle.pad,landerSoft.pad
|
|
||||||
# ---- A tank runs out, and gravity is patient ----
|
# ---- A tank runs out, and gravity is patient ----
|
||||||
#
|
#
|
||||||
# The thruster is held from the first frame to the last and it still crashes. Fuel is a byte
|
# The thruster is held from the first frame to the last and it still crashes. Fuel is a byte
|
||||||
|
|||||||
+53
-2
@@ -1608,7 +1608,10 @@ EOT
|
|||||||
# the ACCELERATION still leaves an average velocity, so it drifts upward slowly and this is
|
# the ACCELERATION still leaves an average velocity, so it drifts upward slowly and this is
|
||||||
# caught early rather than left to settle.
|
# 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
|
# EARLY, and that is the point of 900 thousand cycles. Earlier again than it used to be: the
|
||||||
|
# window grew to two rows when the messages moved into it, and by 1.5 million the lander had
|
||||||
|
# climbed to row nine and was mostly BEHIND the status bar - which is the window doing exactly
|
||||||
|
# what it is meant to and left the check counting six pixels of a forty pixel lander. This program starts almost at once - the
|
||||||
# first guess at where to look was ten million cycles in, on the assumption that taking a
|
# 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
|
# 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
|
# capture near the start is worth far more than a tuned one: there is much less between it and
|
||||||
@@ -1619,7 +1622,7 @@ for i in range(400):
|
|||||||
keys += b'\x80' + b'\x00' * 47
|
keys += b'\x80' + b'\x00' * 47
|
||||||
open('$BUILD/lander.keys','wb').write(keys + b'\x00' * 8000)
|
open('$BUILD/lander.keys','wb').write(keys + b'\x00' * 8000)
|
||||||
"
|
"
|
||||||
timeout 30 "$EMU" --fast --cycles 1500000 --keyboard "$BUILD/lander.keys" \
|
timeout 30 "$EMU" --fast --cycles 900000 --keyboard "$BUILD/lander.keys" \
|
||||||
--screen "$BUILD/lander.ppm" --disk "$ROOT/Tests/build/disks/cosmos.img" \
|
--screen "$BUILD/lander.ppm" --disk "$ROOT/Tests/build/disks/cosmos.img" \
|
||||||
--ram-disk 2048 "$BUILD/cosmos.bin" > "$BUILD/lander.out" 2>&1 || true
|
--ram-disk 2048 "$BUILD/cosmos.bin" > "$BUILD/lander.out" 2>&1 || true
|
||||||
read -r MOON SKY SHIP SHIPLEFT SHIPRIGHT <<EOT
|
read -r MOON SKY SHIP SHIPLEFT SHIPRIGHT <<EOT
|
||||||
@@ -1707,6 +1710,54 @@ EOT
|
|||||||
&& result ok "a held thruster keeps lifting" "row $EARLY early, row $LATE later" \
|
&& result ok "a held thruster keeps lifting" "row $EARLY early, row $LATE later" \
|
||||||
|| result no "a held thruster keeps lifting" "row $EARLY early, row $LATE later"
|
|| result no "a held thruster keeps lifting" "row $EARLY early, row $LATE later"
|
||||||
|
|
||||||
|
# ---- A base speaks in the window, not into the world ----
|
||||||
|
#
|
||||||
|
# The console draws into the map, so a message printed while flying is a message the lander
|
||||||
|
# then flies over - and printing scrolls, so every one of them moved the whole world up a row.
|
||||||
|
# The window is at a screen position and forty cells wide, and neither is true of it.
|
||||||
|
#
|
||||||
|
# The lander is set down gently on the pad it starts above, which loads cargo and says so, and
|
||||||
|
# the message is white - a colour nothing else on this screen uses. Then the throttle opens
|
||||||
|
# and the line goes with it, because a message that outlived the moment would be read as
|
||||||
|
# describing this one.
|
||||||
|
python3 -c "
|
||||||
|
f = (b'\x08' * 6 + b'\x00' * 10) * 60
|
||||||
|
f += b'\x10' * 10 + b'\x00' * 20
|
||||||
|
open('$BUILD/said.pad','wb').write(f + b'\x00' * 3000)
|
||||||
|
f += b'\x08' * 120
|
||||||
|
open('$BUILD/unsaid.pad','wb').write(f + b'\x00' * 2000)
|
||||||
|
"
|
||||||
|
for which in said unsaid; do
|
||||||
|
timeout 40 "$EMU" --fast --cycles 25000000 --keyboard "$BUILD/lander.keys" \
|
||||||
|
--pad "$BUILD/$which.pad" --screen "$BUILD/$which.ppm" \
|
||||||
|
--disk "$ROOT/Tests/build/disks/cosmos.img" --ram-disk 2048 \
|
||||||
|
"$BUILD/cosmos.bin" > "$BUILD/$which.out" 2>&1 || true
|
||||||
|
done
|
||||||
|
# ---- And the same landing flown on the SECOND controller ----
|
||||||
|
#
|
||||||
|
# A pad holding nothing on nought and the flight on one, so a program that read only the first
|
||||||
|
# controller would sit there and never arrive. That check used to live in a transcript and
|
||||||
|
# stopped saying anything the moment the messages moved off the console, which is what a test
|
||||||
|
# asserting a side effect rather than the thing itself is always one refactor away from.
|
||||||
|
python3 -c "open('$BUILD/idle.pad','wb').write(b'\x00' * 4000)"
|
||||||
|
timeout 40 "$EMU" --fast --cycles 25000000 --keyboard "$BUILD/lander.keys" \
|
||||||
|
--pad "$BUILD/idle.pad" --pad "$BUILD/said.pad" --screen "$BUILD/padone.ppm" \
|
||||||
|
--disk "$ROOT/Tests/build/disks/cosmos.img" --ram-disk 2048 \
|
||||||
|
"$BUILD/cosmos.bin" > "$BUILD/padone.out" 2>&1 || true
|
||||||
|
PADONE="$(countColour "$BUILD/padone.ppm" f0f0f0)"
|
||||||
|
[ "$PADONE" -gt 100 ] \
|
||||||
|
&& result ok "and flies on the second controller too" "$PADONE pixels of message, flown on pad one" \
|
||||||
|
|| result no "and flies on the second controller too" "$PADONE pixels of message"
|
||||||
|
|
||||||
|
SAID="$(countColour "$BUILD/said.ppm" f0f0f0)"
|
||||||
|
UNSAID="$(countColour "$BUILD/unsaid.ppm" f0f0f0)"
|
||||||
|
[ "$SAID" -gt 100 ] \
|
||||||
|
&& result ok "a base says so in the window" "$SAID pixels of message, and none in the map" \
|
||||||
|
|| result no "a base says so in the window" "$SAID pixels of message"
|
||||||
|
[ "$UNSAID" = "0" ] \
|
||||||
|
&& result ok "and opening the throttle wipes it" "the line went with the moment" \
|
||||||
|
|| result no "and opening the throttle wipes it" "$UNSAID pixels of it still there"
|
||||||
|
|
||||||
# ---- The landing pads, carved and coloured ----
|
# ---- The landing pads, carved and coloured ----
|
||||||
#
|
#
|
||||||
# A random walk does not leave flat ground and a lander wants some, so four pads are carved
|
# A random walk does not leave flat ground and a lander wants some, so four pads are carved
|
||||||
|
|||||||
Reference in New Issue
Block a user