Now FTP is where it starts to get tricky, and this is a protocol which pre-dates TCP/IP and as a result has a lot of baggage. If your goal is to back up a ProFile, I think you'd be better off inventing your own protocol. Or just start reading and sending each 512-byte data block in sequence as soon as a client connects to the Lisa's listening TCP port.
Perhaps implementing just a minimum binary transfer ftp is enough... but... I mean, we already have ways to transfer a whole ProFile at the block level via BLU.
I'm thinking more along the lines of a mechanism for getting individual files in/out of a volume, but also being able to send/receive a lot of files at once would be super useful too. Perhaps in the long run this is less of a case for an ftp app, than for a VirtualBox Guest Addition/Tools like thing for LisaEm - ideally I'd like to give LPW a lot of puppet strings and automate running it from an external IDE.
But an ftp app would be a good starting point for it.
The
LOS Manual documents the low level kernel functions such as opening a file and so on that would be needed, but I haven't seen (not that I've looked very deeply either) how to access those syscalls from assembly directly bypassing the pascal libraries.
(Nod to your notice that passing large parameter sets on the stack via LINK/UNLINK is very inefficient and requires a lot of copying. That's a big thing I saw in LOS code when looking at the trace logs, a ton of inefficient shoveling of bits back and forth between caller and callee, it's even worse when the Pascal lib stuff hands off to the assembly side. It's on the order of several dozen instructions wasted just shoveling parameters back and forth through the stack.
As an OT aside, this is one reason why my favorite ISA is SPARC as it has register windows with in/out/global register sets, too bad Oracle killed it and Sun didn't make it. SPARC 4v was very very yummy. I imagine an alternate universe where this is the common ISA instead of x86_64 and how much better it would be....)
But passing pointers to records (structures in C) instead is a good work-around idea the Lisa pascal/Mac guys had.
I have an idea about how to implement a Guest Tools thing in LisaEm without adding any software to LOS itself. At first I was planning on writing a native Lisa app, but I've a better idea. Basically I can wait in the emulator until it goes to supervisor mode (or a specific context), save the registers and then replace a specific MMU segment with a block of code and transfer buffer, then set the PC to point there. The code in that special MMU segment could make calls into the kernel to open file handles, read or write to a file, get/set file metadata (or directory info), and close the file handle. Then when it's done, it could call an F-Line trap much like LisaEm's ROMless facility (i.e. F-Line traps) after it has data to return.
Once the transfer is complete, it can then reset the registers and the MMU segment back to what it was before taking action, and then continue as if nothing changed. So it would be transparent from the LOS side. With some extra work it could even tie into a FUSE filesystem.
What I'm missing is how to call those kernel pascal procedures from assembly. I can tell what the parameters are from the pascal structures and such, but what I'm missing is some sort of mapping to the syscalls, are they A-Line traps? are they fixed addresses? How do I find that out? This is pretty easy stuff in Xenix/UniPlus as syscalls are usually a single trap with a parameter. Here, I suspect they're specific addresses using that A-Line trap mechanism, but... need more info. And is it the same across LOS 1.0, 2.0, 3.0, 3.1, or does it change?
I suppose I could write a small it of code that makes a single call to a single thing and then invokes the debugger so I can see what happened, for example, make a single pascal call to say, open a file, and then log everything that happens from there end to end until it comes back to the next line to see what the kernel syscalls actually look like, but then, to quote
Sal from Futurama "
Whoas! What do I look like, a guy whose not lazy? Don't gets me started"
![Grin ;D](https://lisalist2.com/Smileys/default/grin.gif)
- I suppose if I have to I'll find a way to automate that.
Sorry, it's a bit off topic to this conversation, mostly thinking out-loud for future things.
There's a (predictable) additional issue that the Lisa FS has metadata that you won't find on other operating systems....
my solution was to package everything on the fly into a tar archive with three "files" inside....
The Lisa's format for text files is a little weird --- it's faintly block oriented (files are always sized in multiples of 1K, IIRC), and it uses run-length encoding for runs of spaces. I'm still trying to track down where I saw the format documented (the documentation calls it the "One World Text File Format" or something like that), but here's a bit of Python that can decode it.
Lastly, there is the issue of protected files, which the Lisa OS will refuse to let you open. These files are interesting ones like Pascal compiler (Pascal.obj) and the various tools. It's possible that this more recently-discovered mechanism for jumping into supervisor mode can offer a workaround.
Yup, the Lisa does have a lot of metadata associated with it and it's in several layers (including the actual file name presented to the user from the Desktop manager database - the thing that allows duplicate file names). tar is absolutely a good container for this (as would be something like cpio, or even macbinary though it would have to be a variant of it due to the resource fork thing on the mac.)
I think I recall AEK mentioning that text file RLE compression format for the Lisa Sources. It's used to compress the indentations in Pascal code for example. Interestingly they did have a PackBits implementation, but didn't use it for this and rather they wrote a different one. Oh well.
I wouldn't worry too much about the bozo/protected bit, we have ways to remove that now.
![Smiley :)](https://lisalist2.com/Smileys/default/smiley.gif)
It may be possible that a call to unprotect (or if not it can be done through the deserialize tool.)