Partially working port of stdio to CP/M. I'm not sure this will work; it's

getting way too complicated (stdio is horribly subtle). I think I need to
rethink things.
This commit is contained in:
David Given 2019-06-15 22:22:01 +02:00
parent 1387c8713b
commit 3131dc9915
28 changed files with 153 additions and 39 deletions

View file

@ -44,6 +44,7 @@ for _, plat in ipairs(vars.plats) do
"./core/setjmp/*.c",
"./core/setjmp/*.e",
"./core/stdlib/*.c",
"./core/stdio/*.c",
"./core/string/*.c",
"./core/time/*.c",
"./sys/exit/*.c",

View file

@ -30,6 +30,11 @@ struct FILE {
#define FOPEN_MAX 20
extern FILE *__iotab[FOPEN_MAX];
#define stdin (&__stdin)
#define stdout (&__stdout)
#define stderr (&__stderr)
extern FILE __stdin, __stdout, __stderr;
#define FILENAME_MAX 255
#define TMP_MAX 999
#define L_tmpnam (sizeof("/tmp/") + 15)
@ -38,8 +43,6 @@ extern FILE *__iotab[FOPEN_MAX];
extern int __fillbuf(FILE *_stream);
extern int __flushbuf(int _c, FILE *_stream);
#define getchar() getc(stdin)
#define putchar(c) putc(c,stdout)
#define getc(p) (--(p)->_count >= 0 ? (int) (*(p)->_ptr++) : \
__fillbuf(p))
#define putc(c, p) (--(p)->_count >= 0 ? \

View file

@ -23,14 +23,8 @@ typedef struct FILE FILE;
#define SEEK_CUR 1
#define SEEK_END 2
#define stdin (&__stdin)
#define stdout (&__stdout)
#define stderr (&__stderr)
typedef long int fpos_t;
extern FILE __stdin, __stdout, __stderr;
extern int remove(const char *_filename);
extern int rename(const char *_old, const char *_new);
extern FILE *tmpfile(void);
@ -76,7 +70,10 @@ extern int feof(FILE *_stream);
extern int ferror(FILE *_stream);
extern void perror(const char *_s);
/* Internal function used by several places which is approximately itoa(). */
#define getchar() getc(stdin)
#define putchar(c) putc(c, stdout)
/* Internal function used in several places which is approximately itoa(). */
extern char *_i_compute(unsigned long val, int base, char *s, int nrdigits);
#if ACKCONF_WANT_EMULATED_FILE

View file

@ -76,6 +76,7 @@ name led
{FLOATS?} \
(.e:{TAIL}={PLATFORMDIR}/libem.a \
{PLATFORMDIR}/libsys.a \
{PLATFORMDIR}/libc.a \
{PLATFORMDIR}/libem.a \
{PLATFORMDIR}/libend.a)
linker

View file

@ -9,6 +9,11 @@
#include <cpm.h>
#define CPM_FAKE_FILE ((FILE*)1)
#define stdin CPM_FAKE_FILE
#define stdout CPM_FAKE_FILE
#define stderr CPM_FAKE_FILE
struct FILE
{
uint8_t user;
@ -16,7 +21,26 @@ struct FILE
char buffer[128];
};
#define FOPEN_MAX 8
extern FILE* __files[FOPEN_MAX];
#define getc(p) cpm_getc(p)
#define putc(c, p) cpm_putc(c, p)
#define feof(p) cpm_feof(p)
#define ferror(p) cpm_ferror(p)
#define clearerr(p) cpm_clearerr(p)
extern int cpm_putc(int c, FILE* stream);
extern int cpm_getc(FILE* stream);
#if 0
#define getc(p) (--(p)->_count >= 0 ? (int) (*(p)->_ptr++) : \
__fillbuf(p))
#define putc(c, p) (--(p)->_count >= 0 ? \
(int) (*(p)->_ptr++ = (c)) : \
__flushbuf((c),(p)))
#define feof(p) (((p)->_flags & _IOEOF) != 0)
#define ferror(p) (((p)->_flags & _IOERR) != 0)
#define clearerr(p) ((p)->_flags &= ~(_IOERR|_IOEOF))
#endif
#endif

View file

@ -114,4 +114,12 @@ extern void cpm_overwrite_ccp(void);
/* 37 */ extern uint8_t cpm_reset_drives(uint16_t drive_bitmap);
/* 40 */ extern uint8_t cpm_write_random_filled(FCB* fcb);
/* File descriptor emulation */
struct FCBE
{
FCB fcb; /* drive 0 means the console */
uint8_t user;
};
#endif

3
plat/cpm/libsys/fcb.c Normal file
View file

@ -0,0 +1,3 @@
#include <stdio.h>
#include <cpm.h>

20
plat/cpm/libsys/fclose.c Normal file
View file

@ -0,0 +1,20 @@
#include <stdio.h>
#include <errno.h>
#include <cpm.h>
int fclose(FILE* stream)
{
if (stream == CPM_FAKE_FILE)
return 0;
if (fflush(stream))
return;
cpm_get_set_user(stream->user);
if (cpm_close_file(&stream->fcb) == 0xff)
{
errno = EIO;
return -1;
}
return 0;
}

9
plat/cpm/libsys/feof.c Normal file
View file

@ -0,0 +1,9 @@
#include <stdio.h>
#include <errno.h>
#include <cpm.h>
int cpm_feof(FILE* stream)
{
return 0;
}

8
plat/cpm/libsys/ferror.c Normal file
View file

@ -0,0 +1,8 @@
#include <stdio.h>
#include <errno.h>
#include <cpm.h>
int cpm_ferror(FILE* stream)
{
return 0;
}

12
plat/cpm/libsys/fflush.c Normal file
View file

@ -0,0 +1,12 @@
#include <stdio.h>
#include <errno.h>
#include <cpm.h>
int fflush(FILE* stream)
{
if (stream == CPM_FAKE_FILE)
return 0;
errno = EBADF;
return -1;
}

36
plat/cpm/libsys/getc.c Normal file
View file

@ -0,0 +1,36 @@
#include <stdio.h>
#include <errno.h>
#include <cpm.h>
struct buffer
{
uint8_t mx;
uint8_t nc;
uint8_t c[128];
};
static struct buffer buffer;
static uint8_t pos;
int read_from_console(void)
{
while (pos == buffer.nc)
{
/* Refill buffer. */
buffer.mx = sizeof(buffer.c);
buffer.nc = 0;
cpm_readline((uint8_t*) &buffer);
pos = 0;
}
return buffer.c[pos++];
}
int cpm_getc(FILE* stream)
{
if (stream == CPM_FAKE_FILE)
return read_from_console();
errno = EBADF;
return -1;
}

17
plat/cpm/libsys/putc.c Normal file
View file

@ -0,0 +1,17 @@
#include <stdio.h>
#include <errno.h>
#include <cpm.h>
int cpm_putc(int c, FILE* stream)
{
if (stream == CPM_FAKE_FILE)
{
cpm_conout(c);
if (c == '\n')
cpm_conout(c);
return 0;
}
errno = EBADF;
return -1;
}

View file

@ -3,6 +3,7 @@
* $Revision$
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
@ -13,37 +14,11 @@ ssize_t read(int fd, void* buffer, size_t count)
short save;
unsigned char before_n;
/* We're only allowed to read from fd 0, 1 or 2. */
if ((fd < 0) || (fd > 2))
if (fd != 0)
{
errno = EBADF;
return -1;
}
/* We need room for at least 1 char plus '\n'. */
if (count < 2)
{
errno = EINVAL;
return -1;
}
/* Make room to append '\n' later. */
before_n = count > 255 ? 255 : count - 1;
/* Borrow 2 bytes of RAM before the buffer. */
/* This might overwrite count!!! */
save = ((short*)buffer)[-1];
/* Read one line from the console. */
((unsigned char*)buffer)[-2] = before_n;
cpm_readline((uint8_t*)buffer - 2);
before_n = ((unsigned char*)buffer)[-1];
((char*)buffer)[before_n] = '\n'; /* Append '\n'. */
((short*)buffer)[-1] = save; /* Give back borrowed bytes. */
/* Echo '\n' to console. */
cpm_printstring("\r\n$");
return (int)before_n + 1;
return fread(buffer, 1, count, stdin);
}