The orbit check is back, and osFileRead says it reads in blocks
Placing a state retired the reason the orbit check was deleted. Reaching a given orbit through the controls takes a sustained burn while holding height, and the phase of that burn against the gravity tick - one frame in ten - decides whether the thruster is seen at all, so two pad files a frame apart fly differently. The old check passed against one disk and failed against another, which is a check measuring the boot time rather than the physics. Placed at eighty sideways it climbs to row 51, falls to row 190, and climbs again to row 20 - and the turning points are BROAD, tens of pixels across, so the samples have nothing like the margin problem the old one had. Three claims: it climbs, it turns over on its own, and it comes round again no lower than the first time. Both halves of the mechanic are separately caught. Without the outward push it sinks and lands and never climbs; without the exchange it climbs away and never comes back, which is the one way trip the whole thing exists to prevent. ---- And osFileRead writes whole blocks, which nothing said ---- A disk is read a block at a time, so a sixteen byte file still puts 256 bytes where it is told to. Reserving exactly the file's length writes over whatever follows - a quiet corruption rather than a refusal, and it looks like a bug somewhere else entirely. It cost an afternoon here: the state buffer sat in front of the view tables, so the program read its state, wiped the numbers every gauge draws from, and left immediately. Said now in services.asm beside the vector and in the CosmOS manual, along with the pattern that works: reserve the length rounded up to the next 256, read into that, and copy the parts wanted where they are wanted. The orbit fixture also needs its own keyboard file. The shared one holds a key down every forty eight bytes for the held-thruster check, which would fly this orbit as well as measure it.
This commit is contained in:
@@ -1259,7 +1259,7 @@ Those numbers are written down once, in `Programs/CosmOS/Source/services.asm`, w
|
|||||||
| osReadLine | DP0 names somewhere to put a line, B says how much room there is. Reads one from the console, with the shell's own editing - arrows, Home, End, Delete - but not its history. Q comes back holding how long it was. The console is left in whatever mode it was found in. |
|
| osReadLine | DP0 names somewhere to put a line, B says how much room there is. Reads one from the console, with the shell's own editing - arrows, Home, End, Delete - but not its history. Q comes back holding how long it was. The console is left in whatever mode it was found in. |
|
||||||
| osExit | Gives the machine back. Does not return. |
|
| osExit | Gives the machine back. Does not return. |
|
||||||
| osArgument | DP0 names somewhere to put whatever followed the run command, B says how much room there is. |
|
| osArgument | DP0 names somewhere to put whatever followed the run command, B says how much room there is. |
|
||||||
| osFileRead | DP0 names a file, DP1 says where to put it. Q is zero if it read, and DP3 comes back holding how many bytes there were. |
|
| osFileRead | DP0 names a file, DP1 says where to put it. Q is zero if it read, and DP3 comes back holding how many bytes there were. It writes WHOLE BLOCKS: a sixteen byte file still puts 256 bytes where it is told, so the room given has to be the length rounded up to the next 256. |
|
||||||
| osFileSave | DP0 names a file, DP1 is the bytes, A and B together are how many. Q is zero if it saved, whether or not it was there before. |
|
| osFileSave | DP0 names a file, DP1 is the bytes, A and B together are how many. Q is zero if it saved, whether or not it was there before. |
|
||||||
| osFileDelete | DP0 names a file. Q is zero if it went. |
|
| osFileDelete | DP0 names a file. Q is zero if it went. |
|
||||||
| osFileRename | DP0 is the name a file has, DP1 the name it should have. Q is zero if it moved. |
|
| osFileRename | DP0 is the name a file has, DP1 the name it should have. Q is zero if it moved. |
|
||||||
@@ -1317,6 +1317,13 @@ A file of 256 blocks or more is refused by `osFileRead` rather than partly read,
|
|||||||
|
|
||||||
### Reading A File That Will Not Fit:
|
### Reading A File That Will Not Fit:
|
||||||
|
|
||||||
|
`osFileRead` writes in whole blocks, because a block is what a disk is read in. A sixteen
|
||||||
|
byte file still puts 256 bytes wherever it is pointed, and a caller that reserves exactly the
|
||||||
|
file's length writes over whatever follows it - which is a quiet corruption rather than a
|
||||||
|
refusal, and looks like a bug somewhere else entirely. `DP3` still reports the file's own
|
||||||
|
length; the bytes past it are the rest of the block. Reserve the length rounded up to the next
|
||||||
|
256, read into that, and copy the parts wanted where they are wanted.
|
||||||
|
|
||||||
`osFileRead` hands over a whole file, which settles the question for anything under 64K and settles nothing above it. CosmOS's own source is above it: the sources together are a hundred kilobytes and Data Memory is sixty four. A machine that assembles itself has to be able to read a file bigger than its memory, and this is what that stands on.
|
`osFileRead` hands over a whole file, which settles the question for anything under 64K and settles nothing above it. CosmOS's own source is above it: the sources together are a hundred kilobytes and Data Memory is sixty four. A machine that assembles itself has to be able to read a file bigger than its memory, and this is what that stands on.
|
||||||
|
|
||||||
So there is a second way to ask. `osFileInfo` says how big something is and `osFileBlock` hands over one block of it, and between them a program reads a file of any size through a buffer of 256 bytes.
|
So there is a second way to ask. `osFileInfo` says how big something is and `osFileBlock` hands over one block of it, and between them a program reads a file of any size through a buffer of 256 bytes.
|
||||||
|
|||||||
@@ -41,6 +41,13 @@
|
|||||||
; going out it is A and B together, and neither direction needs a record in memory that
|
; going out it is A and B together, and neither direction needs a record in memory that
|
||||||
; both sides have to agree on the shape of.
|
; both sides have to agree on the shape of.
|
||||||
osFileRead 0d20 ; DP0 names it, DP1 says where. Q is zero if it read, DP3 is how many bytes.
|
osFileRead 0d20 ; DP0 names it, DP1 says where. Q is zero if it read, DP3 is how many bytes.
|
||||||
|
; ---- AND IT WRITES WHOLE BLOCKS ----
|
||||||
|
;
|
||||||
|
; A disk is read a block at a time, so a sixteen byte file still puts
|
||||||
|
; 256 bytes where it is told to. The room given has to be the file's
|
||||||
|
; length ROUNDED UP to the next 256, and a caller that gives exactly
|
||||||
|
; the length writes over whatever follows it. DP3 still says how many
|
||||||
|
; bytes are the file's; the rest is whatever was on the block.
|
||||||
osFileSave 0d21 ; DP0 names it, DP1 is the bytes, A and B are how many. Q is zero if it saved.
|
osFileSave 0d21 ; DP0 names it, DP1 is the bytes, A and B are how many. Q is zero if it saved.
|
||||||
osFileDelete 0d22 ; DP0 names it. Q is zero if it went.
|
osFileDelete 0d22 ; DP0 names it. Q is zero if it went.
|
||||||
osFileRename 0d23 ; DP0 is the name it has, DP1 the name it should have. Q is zero if it moved.
|
osFileRename 0d23 ; DP0 is the name it has, DP1 the name it should have. Q is zero if it moved.
|
||||||
|
|||||||
+57
-25
@@ -1788,35 +1788,67 @@ HOME="$(countColour "$BUILD/ceiling22000000.ppm" f0f0f0)"
|
|||||||
&& result ok "and gravity brings it back from there" "the warning went with the height" \
|
&& result ok "and gravity brings it back from there" "the warning went with the height" \
|
||||||
|| result no "and gravity brings it back from there" "$HOME pixels still up"
|
|| result no "and gravity brings it back from there" "$HOME pixels still up"
|
||||||
|
|
||||||
# ---- Orbit, which is measured and not checked here ----
|
# ---- Orbit, which can be checked again now it can be placed ----
|
||||||
#
|
#
|
||||||
# Gravity minus the swing outwards. Below orbital speed the pull wins and the lander falls;
|
# Gravity minus the swing outwards. Below orbital speed the pull wins and the lander falls;
|
||||||
# above it the swing wins and the lander climbs; and falling buys sideways speed while
|
# above it the swing wins and it climbs; and falling buys sideways speed while climbing spends
|
||||||
# climbing spends it. That is what makes a closed orbit rather than a one way trip, and it
|
# it. That is what makes a closed orbit rather than a one way trip.
|
||||||
# was measured doing it. Placed at 80 sideways and left alone, turning points at:
|
|
||||||
#
|
#
|
||||||
# tick 44 height -1024 sideways 59 apoapse, and it falls away
|
# THERE WAS NO CHECK FOR THIS FOR A LONG TIME, and the reason is worth keeping. Reaching a
|
||||||
# tick 123 height -124 sideways 71 periapse, and it climbs again
|
# given orbit through the controls takes a sustained burn while holding height, and the phase
|
||||||
# tick 165 height -1024 sideways 59
|
# of that burn against the gravity tick - one frame in ten - decides whether the thruster is
|
||||||
# tick 241 height -124 sideways 70
|
# seen at all, so two pad files a frame apart fly differently. A version of this check did
|
||||||
# tick 299 height -1024 sideways 59
|
# exist and passed against one disk and failed against another, which is a check measuring the
|
||||||
# tick 369 height -114 sideways 70
|
# boot time rather than the physics. It was deleted rather than left looking tested.
|
||||||
#
|
#
|
||||||
# Four hundred and eighty ticks with no sign of the amplitude decaying, a period of about a
|
# A state file settles it. Placed at eighty sideways, which is sixteen over orbital, the
|
||||||
# hundred and thirty ticks, which is twenty two seconds of play.
|
# lander climbs, turns over, falls, and climbs again - and the turning points are BROAD, tens
|
||||||
#
|
# of pixels across, so the samples below have nothing like the margin problem the old one did.
|
||||||
# THERE IS STILL NO CHECK FOR IT, and it is still deliberate. The measurement above was taken
|
# The station is parked below the surface out of the way, because it laps every four seconds
|
||||||
# with a build that PLACED the lander at eighty sideways, because reaching orbital speed
|
# and would otherwise wander into the middle of the measurement.
|
||||||
# through the controls takes a sustained burn while holding height, and the phase of that burn
|
python3 -c "
|
||||||
# against the gravity tick - one frame in ten - decides whether the thruster is seen at all.
|
import struct
|
||||||
# Two pad files a frame apart fly differently. That is a fine thing for a game and a poor one
|
open('$BUILD/orbit.state','wb').write(struct.pack('<hhhhhhBBBB',
|
||||||
# for a check.
|
0x14A0, 0, 80, 0, 0x14A0, 2600, 255, 1, 0, 0))
|
||||||
#
|
"
|
||||||
# What would make it checkable is still the same thing: a way to put the lander somewhere with
|
# Its own keyboard file and a silent pad. $BUILD/lander.keys holds a key down every forty
|
||||||
# a velocity, without flying it there, which is now wanted by four separate untested paths.
|
# eight bytes for the held-thruster check, which would fly this orbit as well as measure it.
|
||||||
# The other candidate is a hand flown recording of an orbit, the way the delivery below is a
|
python3 -c "open('$BUILD/fly.keys','wb').write(b'Lander\n' + b'\x00' * 8000)"
|
||||||
# hand flown delivery. Until one of those exists this is verified by somebody measuring it,
|
python3 -c "open('$BUILD/none.pad','wb').write(b'\x00' * 60000)"
|
||||||
# and said so here rather than left looking tested.
|
cp "$ROOT/Tests/build/disks/cosmos.img" "$BUILD/orbit.img"
|
||||||
|
"$ROOT/SplitDisk" put "$BUILD/orbit.img" "$BUILD/orbit.state" /lander.state > /dev/null
|
||||||
|
for when in 3000000 13000000 25000000 37000000; do
|
||||||
|
timeout 60 "$EMU" --fast --cycles $when --keyboard "$BUILD/fly.keys" \
|
||||||
|
--pad "$BUILD/none.pad" --screen "$BUILD/orbit$when.ppm" \
|
||||||
|
--disk "$BUILD/orbit.img" --ram-disk 2048 \
|
||||||
|
"$BUILD/cosmos.bin" > "$BUILD/orbit.out" 2>&1 || true
|
||||||
|
done
|
||||||
|
read -r LOWONE HIGHONE LOWTWO HIGHTWO <<EOT
|
||||||
|
$(python3 -c "
|
||||||
|
def height(path):
|
||||||
|
d = open(path, 'rb').read()
|
||||||
|
width = int(d[:40].split()[1])
|
||||||
|
px = d[d.index(b'255\n') + 4:]
|
||||||
|
ship = [i // width for i in range(len(px) // 3)
|
||||||
|
if px[i * 3:i * 3 + 3] == bytes.fromhex('d8c048')]
|
||||||
|
return min(ship) if ship else -1
|
||||||
|
print(height('$BUILD/orbit3000000.ppm'), height('$BUILD/orbit13000000.ppm'),
|
||||||
|
height('$BUILD/orbit25000000.ppm'), height('$BUILD/orbit37000000.ppm'))
|
||||||
|
" 2>/dev/null || echo "-1 -1 -1 -1")
|
||||||
|
EOT
|
||||||
|
# A smaller row is higher up. Fifty pixels of change either way, against turning points that
|
||||||
|
# are flat to within ten - so this is measuring the turn and not the sampling.
|
||||||
|
[ "$HIGHONE" -lt "$(( LOWONE - 50 ))" ] && [ "$HIGHONE" -gt 0 ] \
|
||||||
|
&& result ok "a lander over orbital speed climbs" "row $LOWONE became row $HIGHONE" \
|
||||||
|
|| result no "a lander over orbital speed climbs" "row $LOWONE became row $HIGHONE"
|
||||||
|
# And turns over on its own, with nothing touched: the climb spends the speed that bought it.
|
||||||
|
[ "$LOWTWO" -gt "$(( HIGHONE + 50 ))" ] \
|
||||||
|
&& result ok "and then falls again, which is an apoapse" "row $HIGHONE became row $LOWTWO" \
|
||||||
|
|| result no "and then falls again, which is an apoapse" "row $HIGHONE became row $LOWTWO"
|
||||||
|
# Round again, and no lower than the first time: the exchange is a trade, not a leak.
|
||||||
|
[ "$HIGHTWO" -lt "$(( LOWTWO - 50 ))" ] && [ "$HIGHTWO" -le "$HIGHONE" ] \
|
||||||
|
&& result ok "and round again without decaying" "$HIGHONE, $LOWTWO, then $HIGHTWO" \
|
||||||
|
|| result no "and round again without decaying" "$HIGHONE, $LOWTWO, then $HIGHTWO"
|
||||||
|
|
||||||
# ---- A delivery, flown by hand, and what it cost ----
|
# ---- A delivery, flown by hand, and what it cost ----
|
||||||
#
|
#
|
||||||
|
|||||||
Reference in New Issue
Block a user