... so e.g. filesystem binaries could be linked to device-/architecture-specific part on load, not build time.
For example the fsibm could be linked to a block device driver that could be either wd1770, scsi or vc1571, vc1571 could pull in an IEC driver, and scsi could be linked to either the hardware scsi driver, or an USB-driver...
fsiec could be linked to the hardware device driver on load as well
Currently there are two shells - the old "shell" and the new "lsh". Not all functionality has been implemented in lsh yet, so shell keeps being around.
Extending lsh to completely take over from "shell" would allow to clean up the "shell" code, and allow to separate out the "mon" (which is currently mangled with the old shell) to be come a first class program on its own.
The C64 serial bus is very slow. My usual workaround is to use my IEEE488 interface for any serious work (which is also supported by GeckOS of course :-)
However, not everyone has this, so maybe we can employ a derivation of a fastloader protocol when reading files from disk. (which would help a lot, as basically all commands are loaded from disk before execution).
Open issues:
can we partially load a file (or load it blockwise) using such a protocol, to not block the OS when multitasking? E.g. creating a pipe that inputs from disk, and loads multiple commands will have to have interleaved reads from disk.
This greatly helps debugging stuff after a program has been loaded - and relocated somewhere into the memory.
A "right" place would be the thread table, and a new call to get some information from there.
A "sufficient" place would probably be the task table, and extend the existing GETINFO call, but that only gives the address of the first thread, not the others.
This is related to the fact that one command (e.g. PS) uses PCBUF to get information from the kernel, tries, to write it to STDOUT, so it locks PCBUF during this time, while the shell still tries to open the down-pipe process, which is also using PCBUF to open the file and FORK.
It would be good if there were a build chain that would automatically run some test programs in an emulator, and check the results to see if something got broken.
This could potentially be implemented using e.g. an emulator like the VICE Commodore emulator.
When building the slipd, the xa from ubuntu (version 2.3.5) bails out with rsh.a65:line 688: 2ed0:65816 mode used/required error rsh.a65:line 701: 2eed:65816 mode used/required error
that refer to uses of "flib2osa_w" and "flib2osa_r", which translate to lib6502/libjmp.a65:#define flib2osa_r LIB6502-6 /* maps lib fileno to OS/A65 stream */ lib6502/libjmp.a65:#define flib2osa_w LIB6502-3 /* maps lib fileno to OS/A65 stream */
where "LIB6502" is defined as late-binding label, i.e. using "-LLIB6502"
Implement Job Control in lsh, i.e. being able to stop, put in background and put in foreground of commands (i.e. jobs = PGRPs):
Use STREAMS "line discipline"
On PUTC,
-- if Ctrl-Z -> SIGSTP to PGRP tasks, send SIGCHLD to parent
Shell manages jobs (PGRP)
-- SIGCONT to children on fg/bg
improve TTY handling based on MORE Fix (Issue #27 )
Tasks get a PROCESS GROUP (PGRP), inherited from parent
Fork can create new/use PGRP so tasks can be grouped into jobs by shell (creted PGRP Id is same as task ID of forked child, so returned task ID value can be reused)
STREAMS get an optional "line discipline"
-- if set
--- STREAM gets a PGRP attached
---- On GETC, if PGRP does not match block
---- On PUTC,
----- if Ctrl-C -> signal (all) PGRP tasks SIGTERM
----- if Ctrl-D -> EOF
In the monitor, there is
.asc "COPYCON^@dup^@cd^@DevCmd^@copy^@"
This breaks if there is a pre-processor define like
#define DUP 123
As a mitigation you have to split the string constant like so
.asc "COPYCON^@d","UP^@cd^@DevCmd^@copy^@"
The recent Issue #14 has shown that fsiec does not care about the state of the disk drive. As it seems some operations seem to be "interruptive" when done in the middle of other operations, like closing a file while loading a directory.
While that does not should be a problem in general, some protection should be throught of:
don't load a directory in parallel (this has secaddr =0 and a second open would conflict with a previous one
Defer some operations while loading a directory (e.g. closing a file)
wc, cat, hexdump, and more use the basically the same code to iterate through the input parameters, interpret them as files to read, and read them. The file loop is a copy/paste code, so should be factored out into a common included code file.
On cbm8x96, ps shows the same exec address for lsh and ps, which is either in the lib6502, or not set correctly
when, in c64, running two instances of ps at the same time (one "ps" from the lsh, one "c:ps" from the old style shell on the second console), the exec address of the second ps is inconsistent from different runs, and seemingly unplausible values (like below the one started at the beginning of memory (with exec currently at 237b)
For example, the C64 boot "ROM" segment addresses need to be manually managed in the Makefile depending on the size of the actually assembled segments. And then the available RAM needs to be fed back into c64rom.a65 to let lib6502 know what it can allocate.
I'd rather have some (set of) defined kernel and program images, and build them into a boot image using a proper tool automagically.
The streams interface is horribly slow as it requires one kernel call per character for reading and another for writing. Previous attempts to speed up have not brought the necessary results (see the GETB/PUTB calls).
A new approach will be as follows:
STRMAP: map a user space buffer to the receiving resp. sending end of a stream. A buffer can be more than 256 byte in length.
STRPUSH / STRPULL to send resp. receive data into these mapped buffers, where only the number of bytes put to / taken from the buffer are exchanged as parameters, and the kernel copies the data between the user space and kernel space buffers
The buffer can be of different types:
contiguous: like a single fread() resp. fwrite() to/from a single buffer
circular: a circular buffer
send/receive: STRPUSH and STRPULL are interleaved and a two-way send/receive communication is established
Advantages:
(hopefully) better speed, e.g. lib6502 can map the full segment buffer and the only loop over STRPULLs on load. The filesystem can use a circular buffer, the kernel will translate.
the buffer mapping is stored in the kernel and does not need to be re-calculated every time
potential to extend to zero-copy transfers (but unclear yet how the remapping protocol will work)
the send/receive code can replace the global SYSBUF/PCBUF mechanism, and related semaphore handling
Disadvantages:
kernel/library size increases
only a single task should allow to map a buffer (for resource reasons). the others (if any) still need to use the single-byte interface. Devices will also use the single-byte interfaces
some sys calls /may/ require mapping the buffer on 256 byte boundaries (e.g. FORK) to avoid remapping in-between processing
Some files still have non-ASCII/non-ISO-Latin-1/non-UTF-8 character in them, most likely coming from edits ages ago on the Atari ST, using its character encoding (e.g. ΓΆ as $94).
The target encoding should be UTF-8 but it needs to be checked if xa65 can cope with this.
An extended "ps" command (e.g. -t option) could show information on threads as well, esp. if they are waiting e.g. on semaphores etc.
Needs an extended GETINFO or new THREADINFO call (preferrably the first)
... to print out diagnostic information on the environment (like map of allocated zeropage, map of allocated memory, statistics on tasks like total used memory etc)
Would probably need some entry point into lib6502 to get the necessary information.
The MORE command reads files and pages them on output. After each page MORE waits for user input to show the next page of content.
When MORE is used to pipe files via stdin, however, it still reads the user input from stdin, where the actual data is coming from - so it immediately continues.
In early unix programs, stdin, stdout and stderr were actually the very same file, and commands like the unix "more" were reading from stderr.
when a program is started from lsh (e.g. the "ps" command), each time, you can see that the memory is reused, but zeropage addresses are always relocated to new addresses, so it seems zeropage is not freed when the program terminates.