This is a package which provides an implementation of the standard STDIO library for the Rex. This library is based on the z88dk STDIO library.
This is a pre-release version of the library, for testing. Eventually it is hoped to include the library in the RexDk release.
The STDIO distribution contains eleven main files in the top level directory (as well as sources and some informational files):
stdio.h, fcntl.h, errno.h
-- These header files must be copied to rexdk/include/.
stdio-so.lib, printf.lib
-- These library files must be copied to rexdk/lib/clibs/ and should be linked using
-lstdio-so -lprintf on the zcc command line.
stdio1.rex, stdio2.rex, stdio3.rex
-- These are the Rex addins which contain the STDIO library routines.
These addins must be loaded on the Rex before a program which uses STDIO can run.
rex_crt0.asm, rxl_crt0.asm, rexstreams.asm
-- These are replacements for the standard RexDk startup code.
Amongst other things, these are responsible for allowing space in the RAM area for the
file descriptors and other important data and for the cleanup code which
closes open files on addin exit.
These files should be fully compatible with code which does not use STDIO so can just replace
the standard versions.
They should be copied to rexdk/lib/.
For STDIO Version 0.3.
This section only documents non-standard behaviour. Refer to C or POSIX documentation for standard description.
The following standard functions and other items from stdio.h are implemented: EOF, NULL, FILENAME_MAX, FOPEN_MAX, SEEK_CUR, SEEK_END, SEEK_SET, FILE, stdin, stdout, stderr, clearerr, fopen, freopen, fdopen, fclose, fgets, fputs, fputc, fgetc, ungetc, feof, puts, ftell, fgetpos, fsetpos, rewind, fseek, gets, putc, putchar, getchar, printf, fprintf, sprintf, vfprintf, scanf, fscanf, sscanf, rename, remove.
The following standard system calls and other items from fcntl.h/unistd.h are implemented: O_RDONLY, O_WRONLY, O_RDWR, O_APPEND, O_CREAT, O_TRUNC, open, creat, close, read, write, lseek, ftruncate.
The addin startup code needs to be told that the STDIO library is in use. The z88dk has a mechanism to do that but it only functions on source files which are compiled in the same ZCC command line which links the final addin.
If your addin is contained in a single source file, or if you compile all the source files together in a single ZCC command, no special action needs to be taken. The correct startup code should be invoked automatically.
If you compile source files separately and then link them as a separate step
you need to tell the linker information to allow it to use the correct startup code.
To do this, you need to include at least one C file compilation on the link comand line
(I use about.c which just contains data).
In that file you need to include two #pragma statements:
#pragma output ANSIstdio
#pragma output ministdio
Actually, you always need the first of these to use any of the STDIO routines but you only need the second if you use printf (or friends).
If you are not getting the correct startup code, the most likely symptom will be missing symbol names in the link.
See the source code for the test addin (stdiotest) to see this in use.
Input from stdin is handled by putting up a Rex keyboard display. This has the side effect of messing up the display.
Note that even single character input (e.g. getchar) requires
touching the OK button on the keyboard, so it is no use for games.
The console output routine (fputc_cons.c) uses an invisible cursor to keep track of the
current display position on the screen.
It is only possible to affect this cursor by either displaying printable characters
or using some special control characters.
The routine assumes all characters are the same width (which they are not, of course) so the spacing can look rather odd.
The control characters which are handled are:
\t (TAB): skip to next tab stop (every 48)
\f (FF): clear screen and reset cursor to top left
\r (CR): move cursor back to start of row, do not advance to next row
\n (NL/LF): move cursor to start of next row
\5 (ENQ): wait for a button to be pressed (like grc_select())
The cursor automatically wraps to the next row at the end of each row, however text which would be displayed below the bottom of the screen is lost (there is no scrolling).
Implement buffered I/O for fgets/fputs.
Rewrite to incorporate memo access. Should now be complete.
Proof of concept.