The pad was working; the game was told there was not one
0x64 counted only the RECORDED pads. So a controller plugged into Voyager reported its buttons perfectly, and every game asking whether there was a controller was told no - which is exactly what Lunar Porter asked, once, at startup, before falling back to the console for the rest of the run. The cause is worth naming: a front end calls padSet every frame for every pad, so "held nothing" is the commonest thing it says and cannot also mean "there is no pad here". Connected is said separately now. Pad nought is always there behind a window, because the keyboard is behind it - which is the useful answer rather than the literal one. And Pad.asm, which is what should have existed before any of that guessing began. It prints a line whenever a pad changes, and tells apart the three states that look identical from inside a game that will not respond: one nobody noticed, one mapped to nothing, and a mapping that is wrong. WHY A PROGRAM AND NOT A PRINT IN THE FRONT END: because the question is what the MACHINE can see. A front end reporting what it thinks it is sending answers a different question, and the gap between those two is the whole of this bug. It also found that osPrintNumber takes A as the HIGH half - the same way round as the shift register and every other pair here, and not what a byte in A wants. Every value came out 256 times too big. Gravity is one frame in ten rather than six. The ratio between thrust and gravity is the feel; how often the tick comes round is how fast that feel arrives, and one in six was still touchy. Same lander, more time to think. And the verdict waits for a key. It printed and left immediately, taking the screen with it - so the one thing worth seeing, the lander sitting on the ground it had just reached, was gone before it could be looked at. 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
8eb4e4d67e
commit
df50c2f0f8
@@ -769,6 +769,19 @@ touchdownStop:
|
||||
SWI osPrintString
|
||||
INIA 0x0A
|
||||
OUTA 0x00
|
||||
|
||||
; ---- And a look at what happened ----
|
||||
;
|
||||
; The verdict was printed and the program then left immediately, taking the screen with it -
|
||||
; so the one thing anybody wanted to see, the lander sitting on the ground it had just
|
||||
; arrived at, was replaced by a shell prompt before it could be looked at.
|
||||
touchdownWait:
|
||||
INA 0x01
|
||||
INIB 0x01 ; READY
|
||||
AND
|
||||
BRQ touchdownWait
|
||||
INA 0x00
|
||||
|
||||
RSTA
|
||||
SETD.1 Flying
|
||||
STA.1 ; Which ends the loop, and the program tidies up as it always did.
|
||||
@@ -893,7 +906,12 @@ SpeedDown:
|
||||
Gravity:
|
||||
0x01 0x00
|
||||
FallEvery:
|
||||
0d6 ; Gravity one frame in six. Every frame was Jupiter.
|
||||
0d10 ; ---- Gravity one frame in ten ----
|
||||
;
|
||||
; Every frame was Jupiter and one in six was still touchy: the
|
||||
; ratio between thrust and gravity is the FEEL, and how often the
|
||||
; tick comes round is how fast that feel arrives. Slower ticks are
|
||||
; the same lander with more time to think in.
|
||||
FallTick:
|
||||
0d1
|
||||
; A press on a machine with no pad, which has to be a whole burn because it happens once.
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
; What the controllers are doing, as they do it.
|
||||
;
|
||||
; Prints a line whenever any pad changes: which pad, and the byte it is now reporting. That is
|
||||
; the whole of the diagnostic, and it is enough to tell apart the three things that look
|
||||
; identical from inside a game which is not responding.
|
||||
;
|
||||
; Nothing printed at all, and nought pads present: the front end never saw a controller.
|
||||
; A pad present but no lines: it is seen, and the buttons are mapped to nothing.
|
||||
; Lines that do not match the buttons pressed: the mapping is wrong rather than missing.
|
||||
;
|
||||
; ---- Why a program rather than a print in the front end ----
|
||||
;
|
||||
; Because the question is what the MACHINE can see. A front end that printed what it thought
|
||||
; it was sending would answer a different question, and the gap between those two is exactly
|
||||
; where a controller that was detected, mapped and reported still did nothing: the port that
|
||||
; says which pads exist counted only recorded ones, so a game asked whether there was a
|
||||
; controller and was told no while the buttons underneath worked perfectly.
|
||||
;
|
||||
; Written by Anachronaut
|
||||
|
||||
#Include services.asm
|
||||
|
||||
#Program
|
||||
|
||||
#Base 0x5000
|
||||
|
||||
start:
|
||||
SETD.0 Intro
|
||||
SWI osPrintString
|
||||
|
||||
; How many are there, before anybody presses anything. One bit a pad.
|
||||
SETD.0 PresentText
|
||||
SWI osPrintString
|
||||
INA 0x64
|
||||
CALL sayByte
|
||||
INIA 0x0A
|
||||
OUTA 0x00
|
||||
|
||||
INIA 0x01
|
||||
OUTA 0x02 ; Key mode, so q arrives without a Return.
|
||||
|
||||
everyFrame:
|
||||
INA 0x30
|
||||
INIB 0x01
|
||||
AND
|
||||
BRQ everyFrame ; A frame, which is when a pad's recording steps.
|
||||
|
||||
RSTA
|
||||
SETD.2 Which
|
||||
STA.2
|
||||
eachPad:
|
||||
CALL onePad
|
||||
SETD.2 Which
|
||||
LDA.2
|
||||
INCA
|
||||
STA.2
|
||||
INIB 0d4
|
||||
CCF
|
||||
SUB
|
||||
BNQ eachPad
|
||||
|
||||
; q gives the machine back. Anything else typed is ignored, because a pad test that
|
||||
; stopped on a stray keypress would be a poor thing to lean on.
|
||||
INA 0x01
|
||||
INIB 0x01
|
||||
AND
|
||||
BRQ everyFrame
|
||||
INA 0x00
|
||||
INIB 0x71 ; q
|
||||
CCF
|
||||
SUB
|
||||
BNQ everyFrame
|
||||
|
||||
RSTA
|
||||
OUTA 0x02
|
||||
SWI osExit
|
||||
|
||||
; ---- One pad, printed only when it changes ----
|
||||
;
|
||||
; A line a frame for four pads would be two hundred and forty lines a second and unreadable.
|
||||
; What is worth seeing is the moment something goes down or comes up.
|
||||
onePad:
|
||||
; The port is 0x60 plus the pad number, and a port is an immediate byte inside the
|
||||
; instruction that names it - so it cannot be computed, and the four are written out.
|
||||
SETD.2 Which
|
||||
LDA.2
|
||||
BRA padZero
|
||||
DECA
|
||||
BRA padOne
|
||||
DECA
|
||||
BRA padTwo
|
||||
INA 0x63
|
||||
BRI padGot
|
||||
padZero:
|
||||
INA 0x60
|
||||
BRI padGot
|
||||
padOne:
|
||||
INA 0x61
|
||||
BRI padGot
|
||||
padTwo:
|
||||
INA 0x62
|
||||
|
||||
padGot:
|
||||
; Against what it was last time. Last is four bytes, one a pad, so DP1 walks to this one.
|
||||
SETD.1 Last
|
||||
PSHA
|
||||
SETD.2 Which
|
||||
LDA.2
|
||||
DPUA.1
|
||||
POPA
|
||||
LDB.1
|
||||
CCF
|
||||
SUB
|
||||
BRQ padSame ; The same as last frame, so there is nothing to say.
|
||||
|
||||
STA.1 ; Remembered, so the next frame has something to compare with.
|
||||
PSHA
|
||||
LDA.2 ; DP2 is still Which, from working out where in Last to look.
|
||||
INIB 0x30 ; '0'
|
||||
CCF
|
||||
ADD
|
||||
OUTQ 0x00
|
||||
INIA 0x3A ; ':'
|
||||
OUTA 0x00
|
||||
INIA 0x20
|
||||
OUTA 0x00
|
||||
POPA
|
||||
CALL sayByte
|
||||
INIA 0x0A
|
||||
OUTA 0x00
|
||||
padSame:
|
||||
RET
|
||||
|
||||
; ---- One byte, as a number ----
|
||||
;
|
||||
; osPrintNumber takes A and B TOGETHER, A being the high half - which is the same way round as
|
||||
; the shift register and every other pair on this machine, and is not what a byte in A wants.
|
||||
; Passed as it stood, every value came out two hundred and fifty six times too big.
|
||||
sayByte:
|
||||
RSTB
|
||||
CCF
|
||||
ADD
|
||||
MVQB ; The byte, in the low half where it belongs.
|
||||
RSTA ; And nothing in the high one.
|
||||
SWI osPrintNumber
|
||||
RET
|
||||
|
||||
#Data
|
||||
|
||||
#Base 0x3000
|
||||
|
||||
Intro:
|
||||
"Press buttons on a controller. q quits.
|
||||
"
|
||||
PresentText:
|
||||
"Pads present, as a bit each: "
|
||||
|
||||
; One byte a pad, holding what it said last frame.
|
||||
Last:
|
||||
0x00 0x00 0x00 0x00
|
||||
Which:
|
||||
0x00
|
||||
@@ -726,6 +726,7 @@ from every assembly file in it. Several are old programs written for the bare ma
|
||||
| Break | Stops itself twice with SWI osBreak, so that the registers can be seen changing between one stop and the next. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
static uint8_t held[PAD_COUNT];
|
||||
static FILE *recorded[PAD_COUNT];
|
||||
static uint8_t live[PAD_COUNT];
|
||||
static int connected[PAD_COUNT];
|
||||
|
||||
// ---- The frame the recordings advance on ----
|
||||
//
|
||||
@@ -26,6 +27,7 @@ void padReset(void) {
|
||||
for (int n = 0; n < PAD_COUNT; n++) {
|
||||
held[n] = 0;
|
||||
live[n] = 0;
|
||||
connected[n] = 0;
|
||||
// The files are NOT closed or forgotten. They were named on the command line and
|
||||
// outlive a reset, the same as a disk image does: a machine that restarted itself
|
||||
// and lost its controllers would be a strange thing to debug.
|
||||
@@ -41,10 +43,11 @@ void padFromFile(int which, FILE *file) {
|
||||
recorded[which] = file;
|
||||
}
|
||||
|
||||
void padSet(int which, uint8_t heldNow) {
|
||||
void padSet(int which, int isConnected, uint8_t heldNow) {
|
||||
if (which < 0 || which >= PAD_COUNT) {
|
||||
return;
|
||||
}
|
||||
connected[which] = isConnected;
|
||||
live[which] = heldNow;
|
||||
}
|
||||
|
||||
@@ -76,7 +79,10 @@ uint8_t padRead(uint8_t port) {
|
||||
if (port == PAD_PRESENT) {
|
||||
uint8_t there = 0;
|
||||
for (int n = 0; n < PAD_COUNT; n++) {
|
||||
if (recorded[n] != NULL) {
|
||||
// A recording is a pad, and so is anything the front end says is plugged in.
|
||||
// Counting only the recordings meant this said nought on the one machine that
|
||||
// has real controllers, which is the only machine where the answer matters.
|
||||
if (recorded[n] != NULL || connected[n]) {
|
||||
there |= (uint8_t)(1u << n);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,13 @@ void padFromFile(int which, FILE *file);
|
||||
|
||||
// A live pad, set by whatever is watching real hardware. Ignored for a pad that has a file,
|
||||
// so a recording always wins over whatever somebody happens to be holding.
|
||||
void padSet(int which, uint8_t held);
|
||||
//
|
||||
// CONNECTED IS SAID SEPARATELY FROM HELD, and it has to be: a front end calls this every
|
||||
// frame for every pad, so "held nothing" is the commonest thing it says and cannot also mean
|
||||
// "there is no pad here". Getting that wrong made 0x64 answer nought with a controller
|
||||
// plugged in, and a game that asked whether there was one was told no while the device
|
||||
// underneath was reporting its buttons perfectly.
|
||||
void padSet(int which, int connected, uint8_t held);
|
||||
|
||||
void padTick(unsigned long now);
|
||||
uint8_t padRead(uint8_t port);
|
||||
|
||||
@@ -120,7 +120,14 @@ static int keyTake(void) {
|
||||
static void readPads(void) {
|
||||
for (int n = 0; n < PAD_COUNT; n++) {
|
||||
uint8_t held = 0;
|
||||
// ---- Pad nought is always there, because the keyboard is behind it ----
|
||||
//
|
||||
// Which is the useful answer rather than the literal one: a game that asks for a
|
||||
// controller and finds none falls back to whatever the console can tell it, and
|
||||
// behind a window the console is the worse of the two ways to read the same keys.
|
||||
int there = (n == 0);
|
||||
if (IsGamepadAvailable(n)) {
|
||||
there = 1;
|
||||
if (IsGamepadButtonDown(n, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) { held |= PAD_RIGHT; }
|
||||
if (IsGamepadButtonDown(n, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) { held |= PAD_LEFT; }
|
||||
if (IsGamepadButtonDown(n, GAMEPAD_BUTTON_LEFT_FACE_DOWN)) { held |= PAD_DOWN; }
|
||||
@@ -163,7 +170,7 @@ static void readPads(void) {
|
||||
if (IsKeyDown(KEY_ENTER)) { held |= PAD_START; }
|
||||
if (IsKeyDown(KEY_TAB)) { held |= PAD_SELECT; }
|
||||
}
|
||||
padSet(n, held);
|
||||
padSet(n, there, held);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ from `make`, not from here.
|
||||
### 1. Recorded output
|
||||
|
||||
`Tests/run.sh` assembles each program named in `Tests/manifest`, runs it, and compares
|
||||
everything it printed against a file in `Tests/expected`. 209 tests, of which 147 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
|
||||
given at all.
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 1543
|
||||
Lander.sbx 1553
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
@@ -42,7 +43,7 @@ outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
crossed.txt 560
|
||||
29 files, 1 directory
|
||||
30 files, 1 directory
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
|
||||
@@ -15,7 +15,8 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 1543
|
||||
Lander.sbx 1553
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
@@ -31,7 +32,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
28 files, 1 directory
|
||||
29 files, 1 directory
|
||||
> drive 1
|
||||
> dir
|
||||
other.txt 28
|
||||
|
||||
@@ -32,7 +32,8 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 1543
|
||||
Lander.sbx 1553
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
@@ -48,7 +49,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
28 files, 1 directory
|
||||
29 files, 1 directory
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
|
||||
@@ -22,7 +22,8 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 1543
|
||||
Lander.sbx 1553
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
@@ -38,7 +39,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
28 files, 1 directory
|
||||
29 files, 1 directory
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
|
||||
@@ -22,7 +22,8 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 1543
|
||||
Lander.sbx 1553
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
@@ -38,7 +39,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
28 files, 1 directory
|
||||
29 files, 1 directory
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
|
||||
@@ -108,7 +108,8 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 1543
|
||||
Lander.sbx 1553
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
@@ -124,7 +125,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
28 files, 1 directory
|
||||
29 files, 1 directory
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
|
||||
@@ -27,7 +27,8 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 1543
|
||||
Lander.sbx 1553
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
@@ -43,7 +44,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
28 files, 1 directory
|
||||
29 files, 1 directory
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
CosmOS
|
||||
> Pad
|
||||
Press buttons on a controller. q quits.
|
||||
Pads present, as a bit each: 1
|
||||
0: 8
|
||||
0: 9
|
||||
0: 1
|
||||
0: 0
|
||||
0: 48
|
||||
0: 0
|
||||
finished
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
[exit 0]
|
||||
@@ -15,7 +15,8 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 1543
|
||||
Lander.sbx 1553
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
@@ -31,7 +32,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
28 files, 1 directory
|
||||
29 files, 1 directory
|
||||
> load
|
||||
load what?
|
||||
> load nosuch.sbx
|
||||
|
||||
@@ -13,7 +13,8 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 1543
|
||||
Lander.sbx 1553
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
@@ -29,7 +30,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
28 files, 1 directory
|
||||
29 files, 1 directory
|
||||
> load Say.sbx
|
||||
loaded, starting at 5000
|
||||
> run the disk took its time
|
||||
|
||||
@@ -22,7 +22,8 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 1543
|
||||
Lander.sbx 1553
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
@@ -38,7 +39,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
28 files, 1 directory
|
||||
29 files, 1 directory
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -149,6 +149,11 @@ for i in 1 2 3 4 5 6 7 8; do "$TOOL" put "$DISKS/sbfs.img" "filler$i.txt" >/dev/
|
||||
"$ROOT/Assembler" -I "$ROOT/Programs/CosmOS/Source" \
|
||||
"$ROOT/Programs/CosmOS/Apps/Lander.asm" -o "$WORK/Lander.sbx" >/dev/null
|
||||
"$TOOL" put "$DISKS/cosmos.img" "$WORK/Lander.sbx" >/dev/null
|
||||
# Pad.sbx says what the controllers are doing, which is the only way to tell a pad nobody
|
||||
# noticed from one that is mapped to nothing.
|
||||
"$ROOT/Assembler" -I "$ROOT/Programs/CosmOS/Source" \
|
||||
"$ROOT/Programs/CosmOS/Apps/Pad.asm" -o "$WORK/Pad.sbx" >/dev/null
|
||||
"$TOOL" put "$DISKS/cosmos.img" "$WORK/Pad.sbx" >/dev/null
|
||||
# Crash.sbx breaks in each of the four ways the system now catches, which is the only way to
|
||||
# reach a fault screen from a recorded test.
|
||||
"$ROOT/Assembler" -I "$ROOT/Programs/CosmOS/Source" \
|
||||
|
||||
@@ -1023,6 +1023,15 @@ padTest | testPrograms/padTest.asm | run | -
|
||||
# is the whole of the game's difficulty in two fixtures.
|
||||
cosmosLanderCrash | CosmOS/Source/cosmos.asm | run | - | 60000000 | disks/cosmos.img | lander.keys | landerFall.pad
|
||||
cosmosLanderSoft | CosmOS/Source/cosmos.asm | run | - | 60000000 | disks/cosmos.img | lander.keys | landerSoft.pad
|
||||
# ---- And the thing that says whether a controller is being seen at all ----
|
||||
#
|
||||
# Three states look identical from inside a game that is not responding: a pad the front end
|
||||
# never noticed, a pad it noticed and mapped to nothing, and a mapping that is simply wrong.
|
||||
# Pad tells them apart by printing what the MACHINE can see, which is a different question
|
||||
# from what a front end thinks it is sending - and the gap between those two is where a
|
||||
# controller that was detected, mapped and reported still did nothing, because the port
|
||||
# saying which pads exist counted only the recorded ones.
|
||||
cosmosPadApp | CosmOS/Source/cosmos.asm | run | - | 30000000 | disks/cosmos.img | pad.keys | padApp.pad
|
||||
# Which disk the registers mean. Several disks are one controller with a drive register
|
||||
# rather than several devices, because a port is an immediate byte inside the instruction
|
||||
# that names it and a program cannot compute one. Run with a single disk, so drive 1 is a
|
||||
|
||||
Reference in New Issue
Block a user