SWI osWhereAmI hands back the path the program was loaded from, on the same terms as osArgument, and Libraries/path.asm joins a name to the place another thing is in. Between them an application can find its own assets: ask where you are, then pathBeside that and the file's name. The answer FOLLOWS THE PROGRAM AND NOT THE PERSON, which is the whole point and the reason the working directory could not serve. A program's assets are relative to the program and its arguments are relative to whoever ran it, and cwd can only be one of them - setting it to the program's own would mean "Play mytune.tune", typed by somebody in their own directory, looked in Play's. It is made absolute before the program starts, because the path the search settled on may be a bare name: a program found where somebody was standing is named by the word that was typed, and a bare name means the working directory - which a program is entitled to move out of. Worked out once, at the start, since where a program came from is a fact about its start and cannot change afterwards. Joining is a LIBRARY and not a service. A service that opened a file relative to the program would need a twin for every file operation there is - read, save, info, block, start, write, done, delete, rename - while one service handing back a path composes with all of them. ---- And the root's own path was "//" ---- Found by the first caller that asks. shellPath prepends a separator in front of whatever string it is given, so being handed the separator itself wrote two of them. Nothing saw it while the only caller was the prompt, which asks where it is only when that is not the root. It is handed an empty string now, and cosmosWhere runs a program from the root. Where.sbx exists to be run rather than read, and is on the test disk twice: at the root, where it is found by the bare word typed, and in /Apps, where it is found by a path that already says where it is. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
101 lines
2.4 KiB
NASM
101 lines
2.4 KiB
NASM
; A program that says where it came from.
|
|
;
|
|
; The dullest thing on the disk, and that is the point of it: osWhereAmI and pathBeside are
|
|
; what an application with assets stands on, and both are much easier to check now, with
|
|
; nothing depending on them, than later inside a game that has gone quiet.
|
|
;
|
|
; Where says the path it was loaded from
|
|
; Where splash.tune says that, and the path of splash.tune beside it
|
|
;
|
|
; ---- The thing worth checking ----
|
|
;
|
|
; The answer follows the PROGRAM and not the person. Run this from the root and it says one
|
|
; thing; walk somewhere else and run the same copy and it says the same thing, because the
|
|
; system worked it out when the program started and a program's own place cannot move under
|
|
; it. A working directory is where the person is standing, and it is what the argument means:
|
|
; "Where notes.txt" asks about a notes.txt in the program's place, not in yours, which is
|
|
; exactly the distinction an application needs and the reason cwd could not serve both.
|
|
|
|
#Include services.asm
|
|
|
|
#Program
|
|
|
|
#Base 0x5000
|
|
|
|
start:
|
|
SETD.0 MyPath
|
|
INIB 0d192
|
|
SWI osWhereAmI
|
|
|
|
SETD.0 FromText
|
|
SWI osPrintString
|
|
SETD.0 MyPath
|
|
SWI osPrintString
|
|
CALL newLine
|
|
|
|
; With nothing after it, that is the whole of what it has to say.
|
|
SETD.0 Given
|
|
INIB 0d64
|
|
SWI osArgument
|
|
SETD.0 Given
|
|
LDA.0
|
|
BRA whereDone
|
|
|
|
SETD.0 MyPath
|
|
SETD.1 Given
|
|
SETD.2 Beside
|
|
INIB 0d192
|
|
CALL pathBeside
|
|
BNQ whereTooLong
|
|
|
|
SETD.0 BesideText
|
|
SWI osPrintString
|
|
SETD.0 Beside
|
|
SWI osPrintString
|
|
CALL newLine
|
|
|
|
whereDone:
|
|
RSTA
|
|
SWI osExit
|
|
|
|
whereTooLong:
|
|
; A path that did not fit is a wrong answer, and saying it would be worse than saying so.
|
|
SETD.0 TooLongText
|
|
SWI osPrintString
|
|
CALL newLine
|
|
INIA 0x01
|
|
SWI osExit
|
|
|
|
newLine:
|
|
SETD.0 NewLine
|
|
SWI osPrintString
|
|
RET
|
|
|
|
#Data
|
|
|
|
#Base 0x3000
|
|
|
|
FromText:
|
|
"loaded from "
|
|
BesideText:
|
|
"beside it: "
|
|
TooLongText:
|
|
"that path would not fit"
|
|
NewLine:
|
|
0x0A 0x00
|
|
|
|
MyPath:
|
|
#Reserve 0d192
|
|
Beside:
|
|
#Reserve 0d192
|
|
Given:
|
|
#Reserve 0d64
|
|
|
|
; ---- Included last, after both segments have been based ----
|
|
;
|
|
; A #Base says where a whole segment begins and so has to be the first thing in it, and a
|
|
; library brings code and data of its own. Put in front, its #Data would be the first thing
|
|
; in the Data Segment and this program's own #Base would be too late. This is where Lander
|
|
; keeps its seven, for the same reason.
|
|
#Include path.asm
|