Commit 04e387ec authored by Kevin Bracey's avatar Kevin Bracey

* RISC_OSLib msgs module now closes its Messages files on exit.

* strerror/perror now call _kernel_last_oserror and use result
  if errno is unknown.
* _sys_open calls error-returning form of OS_Find so
  _kernel_last_oserror can return something meaningful after
  fopen fails
* All file handling calls set errno to -1 if a _kernel_osfind/
  _kernel_osgbpb etc call returns an error
* These three changes mean that the code sequence

         if ((fp = fopen(file, "rb")) == NULL) {
            perror(progname);
            return 1;
         }

  will now say something useful rather than "No error (errno=0)"
  This could now be used by socklib to get perror to work
  with errors generated by the Internet module.
* ANSILib now outputs proper messages, not just tokens.
parent 0d56fc75
......@@ -80,6 +80,17 @@ DFLAGS =\
-DALLOW_OLD_PATTERNS\
-DSET_MISC_OPTIONS
# ANSILib flags
CLFLAGS =\
-DDEFAULT_TEXT
ALFLAGS =\
-PD "DEFAULT_TEXT SETL {TRUE}"
VLFLAGS =\
-DLIB_SHARED="\"\""\
-DLIB_APCS="\"R\""
# Shared C Library flags
CSFLAGS =\
-I@,^.clib\
......@@ -90,22 +101,18 @@ VSFLAGS =\
-DLIB_SHARED="\"Shared \""\
-DLIB_APCS="\"R\""
VLFLAGS =\
-DLIB_SHARED="\"\""\
-DLIB_APCS="\"R\""
VPATH = @ kernel clib rlib
.SUFFIXES: .o .o_rl .m_o_rl .rm_o .rm_o_rl
#
# Rule patterns
#
.c.o:; ${CC} ${CFLAGS} -fah -o $@ $<
.c.o:; ${CC} ${CFLAGS} -fah ${CLFLAGS} -o $@ $<
.c.o_rl:; ${CC} ${CFLAGS} ${DFLAGS} -o $@ $<
.c.m_o_rl:; ${CC} ${CFLAGS} -ffah ${DFLAGS} -zM -o $@ $<
.c.rm_o:; ${CC} ${CFLAGS} -ffah ${DFLAGS} -zm1 ${CSFLAGS} -o $@ $<
.c.rm_o_rl:; ${CC} ${CFLAGS} -ffah ${DFLAGS} -zm1 ${CSFLAGS} ${STK_EXTN} -o $@ $<
.s.o:; ${OBJASM} ${AFLAGS} $< $@
.s.o:; ${OBJASM} ${AFLAGS} ${ALFLAGS} $< $@
.s.o_rl:; ${OBJASM} ${AFLAGS} $< $@
.s.m_o_rl:; ${OBJASM} ${AFLAGS} $< $@
.s.rm_o:; ${OBJASM} ${AFLAGS} $< $@
......@@ -595,10 +602,10 @@ RISC_OSLib:s.modulewrap: s.modulewrap; ${CP} s.modulewrap $@ ${CPFLAGS}
# Objects whose name isn't the same as their source
#
o.clib: clib.s.cl_obj_r
${OBJASM} ${AFLAGS} -from clib.s.cl_obj_r -to $@
${OBJASM} ${AFLAGS} ${ALFLAGS} -from clib.s.cl_obj_r -to $@
o.kernel: kernel.s.k_obj_r
${OBJASM} ${AFLAGS} -from kernel.s.k_obj_r -to $@
${OBJASM} ${AFLAGS} ${ALFLAGS} -from kernel.s.k_obj_r -to $@
rm_o.bsearch_a: c.bsearch
${CC} ${CFLAGS} -ffah ${DFLAGS} -zm1 ${CSFLAGS} -zkA -o $@ c.bsearch
......@@ -615,8 +622,8 @@ rm_o_rl.rl_modbody: rlib.s.rl_mod_r
rm_o.k_modbody: kernel.s.k_mod_r
${OBJASM} ${AFLAGS} -from kernel.s.k_mod_r -to $@
rm_o.memcpset: s.memcpset s.h_regs
${OBJASM} ${AFLAGS} -from s.memcpset -to $@
rm_o.memcpy: s.memcpy s.h_regs
${OBJASM} ${AFLAGS} -from s.memcpy -to $@
rm_o.initmodule: clib.s.initmod_r
${OBJASM} ${AFLAGS} -from clib.s.initmod_r -to $@
......@@ -628,13 +635,13 @@ rm_o_rl.initmodule: rlib.s.initmod_r
# Objects that require extra flags
#
o.armsys: c.armsys
${CC} ${CFLAGS} -fah ${VLFLAGS} -o $@ c.armsys
${CC} ${CFLAGS} -fah ${CLFLAGS} ${VLFLAGS} -o $@ c.armsys
o.armprof: c.armprof
${CC} ${CFLAGS} -fah ${VLFLAGS} -pcc -o $@ c.armprof
${CC} ${CFLAGS} -fah ${CLFLAGS} ${VLFLAGS} -pcc -o $@ c.armprof
o.string: c.string
${CC} ${CFLAGS} -fah -DSEPARATE_MEMCPY -DSEPARATE_MEMSET -o $@ c.string
${CC} ${CFLAGS} -fah ${CLFLAGS} -DSEPARATE_MEMCPY -DSEPARATE_MEMSET -o $@ c.string
rm_o.armsys: c.armsys
${CC} ${CFLAGS} -ffah ${DFLAGS} -zm1 ${CSFLAGS} ${VSFLAGS} -o $@ c.armsys
......
......@@ -14,12 +14,6 @@
|
Dir <Obey$Dir>
wimpslot -min 1000k
echo amu_machine lib.stubs
|amu_machine lib.stubs
echo amu_machine lib.risc_oslib
amu_machine lib.risc_oslib
echo amu_machine lib.clib
|amu_machine lib.clib
echo amu_machine lib.ansilib
amu_machine lib.ansilib
echo amu_machine lib.stubs lib.risc_oslib lib.riscoslibm lib.clib lib.ansilib
amu_machine lib.stubs lib.risc_oslib lib.riscoslibm lib.clib lib.ansilib
echo MkLibs: all done
......@@ -33,6 +33,7 @@
#include <ctype.h> /* isprint(), isspace() */
#include <string.h> /* for strlen() */
#include <time.h> /* for clock */
#include <errno.h>
/* IMPORTS */
extern int main(int argc, char **argv); /* the point of it all */
......@@ -179,6 +180,14 @@ default: /* a good a place as any for an unknown machine */
/* system dependent I/O routines ... */
/* Riscos has a second distinguished FILEHANDLE value, to indicate that */
/* a file is a keyboard and/or vdu, which can't be read or written using */
/* Riscos file operations (or at any rate, couldn't when the library was */
/* originally implemented). */
#define TTYHANDLE 0
#define istty(fh) ((fh) == TTYHANDLE)
static int _error_recursion;
void _sys_msg(const char *s)
{ /* write out s carefully for intimate system use. */
......@@ -208,9 +217,9 @@ static int isttyname(const char *s)
FILEHANDLE _sys_open(const char *filename, int openmode)
{ /* nasty magic number interface for openmode */
static const int modtab[6] = { /* r = */ 0x040, /* r+ = */ 0x0c0,
/* w = */ 0x4c0, /* w+ = */ 0x4c0,
/* a = */ 0x3c0, /* a+ = */ 0x3c0 };
static const int modtab[6] = { /* r = */ 0x04c, /* r+ = */ 0x0cc,
/* w = */ 0x4cc, /* w+ = */ 0x4cc,
/* a = */ 0x3cc, /* a+ = */ 0x3cc };
if (isttyname(filename)) return TTYHANDLE;
else {
char *name = (char *)filename; /* yuk yuk yuk yuk yuk */
......@@ -220,45 +229,119 @@ FILEHANDLE _sys_open(const char *filename, int openmode)
_kernel_osfile_block fb;
/* maybe stamp file with current datestamp */
if ((openmode & 16) || /* update timestamp requested */
(openmode >= 4 && openmode <= 9)) /* or mode = w, w+, or a */
{ if (_kernel_osfile(9, name, &fb) <0) /* (contents of fb irrelevant) */
if ((openmode & OPEN_T) || /* update timestamp requested */
(openmode & OPEN_W) ||
(openmode & ~OPEN_B) == OPEN_A) /* or mode = w, w+, or a */
{ if (_kernel_osfile(9, name, &fb) == _kernel_ERROR)
{ if (_kernel_last_oserror()->errnum == 0x108c9)
{ (void)_kernel_osfile(9, name, &fb); /* to restore the error */
errno = -1;
return NONHANDLE; /* (Protected disc) */
}
}
}
retry_open:
fh = _kernel_osfind(osmode & 0xff, name);
if (osmode <= 0x0c0) /* r or r+ */
if (osmode <= 0x0cc) { /* r or r+ */
if (fh == _kernel_ERROR) errno = -1;
return (fh <= 0) ? NONHANDLE : /* not found */
fh;
else if (fh > 0) {
if ((osmode == 0x4c0) || (size == 0))
} else if (fh > 0) {
if ((osmode == 0x4cc) || (size == 0))
if (_kernel_osargs(3, fh, 0) == _kernel_ERROR) {
_kernel_osfind(0, (char *)fh);
errno = -1;
return NONHANDLE;
}
return fh;
} else if (fh == 0) {
} else if (fh <= 0) {
/* _kernel_osfile(11) creates an empty file of size 'size', of type */
/* given by fb.load, stamped with the current date & time */
fb.load = (openmode & 1) ? 0xffd : 0xfff; /* data : text */
fb.start = 0;
for (; ; size >>= 1) {
if (size < 512) return NONHANDLE; /* probably Disc Full */
if (size < 512) { errno = -1; return NONHANDLE; }
fb.end = size;
if (_kernel_osfile(11, name, &fb) > 0) break;
}
size = 0;
goto retry_open;
}
if (fh == _kernel_ERROR) errno = -1;
return NONHANDLE;
}
}
int _ttywrite(unsigned char *buf, unsigned int len, int flag)
int _sys_istty(FILE *stream)
{
return istty(stream->__file);
}
int _sys_seek(FILEHANDLE fh, long pos)
{
if istty(fh) return 0;
{ int rc = _kernel_osargs(1, fh, (int)pos);
if (rc == _kernel_ERROR) errno = -1;
return rc;
}
}
long _sys_flen(FILEHANDLE fh)
{
int rc = _kernel_osargs(2, fh, 0);
if (rc == _kernel_ERROR) errno = -1;
return rc;
}
int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode)
{ if (istty(fh))
return _ttywrite(buf, len, mode);
else {
_kernel_osgbpb_block b;
b.dataptr = (void *)buf;
b.nbytes = (int)len;
if (_kernel_osgbpb(2, fh, &b) == _kernel_ERROR) {
errno = -1;
return _kernel_ERROR;
} else
return b.nbytes;
}
}
int _sys_read(FILEHANDLE fh, unsigned char *buf, unsigned len, int mode)
{
if (istty(fh))
return _ttyread(buf, (int)len, mode);
else {
_kernel_osgbpb_block b;
b.dataptr = (void *)buf;
b.nbytes = (int)len;
if (_kernel_osgbpb(4, fh, &b) == _kernel_ERROR) {
errno = -1;
return _kernel_ERROR;
} else
return b.nbytes;
}
}
int _sys_ensure(FILEHANDLE fh)
{
if (istty(fh)) return 0;
{ int rc = _kernel_osargs(0xFF, fh, 0);
if (rc == _kernel_ERROR) errno = -1;
return rc;
}
}
int _sys_close(FILEHANDLE fh)
{ if (istty(fh)) return 0;
{ int rc = _kernel_osfind(0, (char *)fh);
if (rc == _kernel_ERROR) errno = -1;
return rc;
}
}
int _ttywrite(const unsigned char *buf, unsigned int len, int flag)
/* behaves like Kgbpb, but outputs to console. */
/* if 'flag' has _IOBIN set then LF's ('\n's) do not have CR prefixed. */
{ while (len-- > 0)
......
......@@ -26,6 +26,7 @@
#include <assert.h> /* for __assert() */
#include <string.h> /* for strerror */
#include <errno.h>
#include "kernel.h"
extern int _fprintf_lf(FILE *fp, const char *fmt, ...);
extern int _sprintf_lf(char *buff, const char *fmt, ...);
......@@ -55,53 +56,14 @@ void __assert(char *expr, char *file, int line)
abort();
}
/* from <string.h> */
char *strerror(int n)
{
static char v[80];
char *s, *t;
switch (n)
{ case 0:
t = "C35";
#ifdef DEFAULT_TEXT
s = "No error (errno = 0)";
#endif
break;
case EDOM:
t = "C36";
#ifdef DEFAULT_TEXT
s = "EDOM - function argument out of range";
#endif
break;
case ERANGE:
t = "C37";
#ifdef DEFAULT_TEXT
s = "ERANGE - function result not representable";
#endif
break;
case ESIGNUM:
t = "C66";
#ifdef DEFAULT_TEXT
s = "ESIGNUM - illegal signal number to signal() or raise()";
#endif
break;
default:
t = "C38";
#ifdef DEFAULT_TEXT
s = "Error code (errno) %d has no associated message";
#endif
break;
extern char *_hostos_error_string(int no, char *buf) {
buf = buf; /* unused */
if (no == -1) {
_kernel_oserror *e = _kernel_last_oserror();
return (e == NULL) ? _kernel_getmessage("unspecified error", "C69") : e->errmess;
} else {
return _kernel_getmessage("unknown error", "C70");
}
s = _kernel_getmessage(s, t);
_sprintf_lf(v, s, n);
return v;
}
/* from <stdio.h> */
void perror(const char *s)
{ if (s != 0 && *s != 0) fprintf(stderr, "%s: ", s);
fprintf(stderr, "%s\n", strerror(errno));
}
/* end of error.c */
......@@ -41,6 +41,7 @@
#include <errno.h>
#include "kernel.h" /* debug */
#include "hostsys.h"
extern char *_kernel_getmessage(char *msg, char *tag);
extern int _fprintf_lf(FILE *fp, const char *fmt, ...);
......@@ -227,13 +228,13 @@ static int _writebuf(unsigned char *buf, int len, FILE *stream)
int flag = stream->__flag;
if (flag & _IOSHARED) /* this is really gross */
{ flag |= _IOSEEK;
stream->__pos = _sys_flen_(fh);
stream->__pos = _sys_flen(fh);
dbmsg("_IOSHARED so zoom to end %d\n", (int)stream->__pos);
}
if (flag & _IOSEEK+_IOBUFREAD)
{
dbmsg("_writebuf seeking to %d\n", (int)stream->__pos);
if (_sys_seek_(fh, (int)stream->__pos) < 0)
if (_sys_seek(fh, (int)stream->__pos) < 0)
{ seterr(stream);
return EOF;
}
......@@ -243,7 +244,7 @@ dbmsg_noNL("_writebuf pop goes the stoat %i, ", fh);
dbmsg_noNL("%X, ", buf);
dbmsg_noNL("%d, ", len);
dbmsg("%X\n", flag);
w = _sys_write_(fh, buf, len, flag);
w = _sys_write(fh, buf, len, flag);
stream->__flag |= _IOADFSBUG;
dbmsg("_sys_write_ returned %d\n", w);
stream->__pos += len - (w & 0x7fffffffL);
......@@ -251,7 +252,7 @@ dbmsg("_sys_write_ returned %d\n", w);
{ seterr(stream);
return(EOF);
}
dbmsg("filelen = %d\n",_sys_flen_(fh)); /* length of this file */
dbmsg("filelen = %d\n",_sys_flen(fh)); /* length of this file */
return 0;
}
......@@ -358,7 +359,7 @@ dbmsg("%s\n", "!= _IOWRITE");
dbmsg("%s\n", "set IODIRTIED");
stream->__flag = (flag |= (_IODIRTIED+_IONOREADS)); /* we are writing */
if (stream->__base == NULL)
{ if (_sys_istty_(stream->__file)) { /* terminal - unbuffered */
{ if (_sys_istty(stream)) { /* terminal - unbuffered */
stream->__ptr = stream->__base = stream->__extrap->__lilbuf;
stream->__bufsiz = 1;
stream->__flag = (flag |= _IONBF);
......@@ -446,10 +447,10 @@ dbmsg("fillbuf negative icnt = %d\n", stream->__icnt);
else {
dbmsg("fillbuf seeking to %d\n", (int)stream->__pos);
if (stream->__flag & _IOADFSBUG) {
_sys_ensure_(fh);
_sys_ensure(fh);
stream->__flag &= ~_IOADFSBUG;
}
if (_sys_seek_(fh, (int)stream->__pos) < 0)
if (_sys_seek(fh, (int)stream->__pos) < 0)
{ seterr(stream);
return EOF;
}
......@@ -469,10 +470,10 @@ dbmsg("fillbuf flag %X\n", stream->__flag);
if ((stream->__flag & (_IOBUFREAD+_IOSEEK)) == 0) {
dbmsg("fillbuf dirty buffer, read into end,seeking to %d\n",(int) stream->__pos+extent);
if (stream->__flag & _IOADFSBUG) {
_sys_ensure_(fh);
_sys_ensure(fh);
stream->__flag &= ~_IOADFSBUG;
}
if (_sys_seek_(fh, (int) stream->__pos + extent) < 0)
if (_sys_seek(fh, (int) stream->__pos + extent) < 0)
{ seterr(stream);
return EOF;
} else stream->__flag |= _IOBUFREAD;
......@@ -490,9 +491,9 @@ dbmsg("at buff %X\n", (int)buff);
dbmsg("READING FROM FILE REQUEST = %d\n", request);
dbmsg("filelen = %d\n",_sys_flen_(fh)); /* length of this file */
dbmsg("filelen = %d\n",_sys_flen(fh)); /* length of this file */
stream->__icnt = 0;
w = _sys_read_(fh, buff, request, stream->__flag);
w = _sys_read(fh, buff, request, stream->__flag);
stream->__flag &= ~_IOADFSBUG;
dbmsg("_sys_read_ returned %d\n", w);
if (w<0) {
......@@ -559,7 +560,7 @@ int fclose(FILE *stream)
}
/* Assert: fd != SYS_OPEN => fh is shared and mustn't be closed */
if (fd == _SYS_OPEN &&
_sys_close_(fh) < 0) res = EOF; /* close real file */
_sys_close(fh) < 0) res = EOF; /* close real file */
if (flag & _IOSBF) free(buff); /* free buffer if system */
if ((flag & _IODELMSK) == _IODEL)
{ char name[L_tmpnam];
......@@ -585,20 +586,20 @@ FILE *freopen(const char *name, const char *mode, FILE *iob)
fclose(iob);
switch (*mode++)
{ default: return(NULL); /* mode is incorrect */
case 'r': flag = _IOREAD; openmode = 0; break;
case 'w': flag = _IOWRITE; openmode = 4; break;
case 'r': flag = _IOREAD; openmode = OPEN_R; break;
case 'w': flag = _IOWRITE; openmode = OPEN_W; break;
case 'a': flag = _IOWRITE | _IOAPPEND;
openmode = 8; break;
openmode = OPEN_A; break;
}
for (;;)
{ switch (*mode++)
{
case '+': flag |= _IOREAD+_IOWRITE, openmode |= 2;
case '+': flag |= _IOREAD+_IOWRITE, openmode |= OPEN_PLUS;
continue;
case 'b': flag |= _IOBIN, openmode |= 1;
case 'b': flag |= _IOBIN, openmode |= OPEN_B;
continue;
}
if (*(mode-1) == 't') openmode |= 16;
if (*(mode-1) == 't') openmode |= OPEN_T;
break;
}
if ((fh = _sys_open(name, openmode)) == NONHANDLE) return NULL;
......@@ -606,7 +607,7 @@ FILE *freopen(const char *name, const char *mode, FILE *iob)
iob->__ptr = iob->__base = NULL; iob->__bufsiz = BUFSIZ;
iob->__flag = flag;
iob->__file = fh;
if (openmode & 8) fseek(iob, 0L, SEEK_END); /* a or a+ */
if (openmode & OPEN_A) fseek(iob, 0L, SEEK_END); /* a or a+ */
return iob;
}
......@@ -654,7 +655,7 @@ FILE *_fopen_string_file(const char *data, int length)
}
int _fisatty(FILE *stream) /* not in ANSI, but related needed for ML */
{ if ((stream->__flag & _IOREAD) && _sys_istty_(stream->__file)) return 1;
{ if ((stream->__flag & _IOREAD) && _sys_istty(stream)) return 1;
return 0;
}
......@@ -840,7 +841,7 @@ int fseek(FILE *stream, long int offset, int whence)
int flag = stream->__flag;
dbmsg_noNL("%s ", "SEEK ENTRY");
if (!(flag & _IOREAD+_IOWRITE+_IOSHARED) || _sys_istty_(fh))
if (!(flag & _IOREAD+_IOWRITE+_IOSHARED) || _sys_istty(stream))
return(2); /* fseek impossible */
switch(whence)
......@@ -852,7 +853,7 @@ case SEEK_CUR:
break;
case SEEK_END:
{ long int filelen, filepos;
filelen = _sys_flen_(fh); /* length of this file */
filelen = _sys_flen(fh); /* length of this file */
dbmsg("filelen in seek = %d\n", (int)filelen);
if (filelen<0) /* failed to read length */
{ seterr(stream);
......@@ -1000,4 +1001,10 @@ FILE *tmpfile()
return f;
}
void perror(const char *s)
{ char b[256];
if (s != 0 && *s != 0) fprintf(stderr, "%s: ", s);
fprintf(stderr, "%s\n", _strerror(errno, b));
}
/* end of stdio.c */
......@@ -461,6 +461,11 @@ void *memset(void *s, _chararg c, size_t n)
#endif
char *strerror(int n)
{ static char v[256];
return _strerror(n, v);
}
size_t strlen(const char *a) /* find number of chars in a string */
{ const char *x = a + 1;
#ifdef _copywords
......@@ -495,4 +500,22 @@ size_t strlen(const char *a) /* find number of chars in a string */
return a - x;
}
/* End string processing library */
#include <errno.h>
char *_strerror(int n, char *v)
{
switch (n)
{ case 0:
return _kernel_getmessage("No error (errno = 0)", "C35");
case EDOM:
return _kernel_getmessage("EDOM - function argument out of range", "C36");
case ERANGE:
return _kernel_getmessage("ERANGE - function result not representable", "C37");
case ESIGNUM:
return _kernel_getmessage("ESIGNUM - illegal signal number to signal() or raise()", "C66");
default:
return _hostos_error_string(n, v);
}
}
/* End string.c */
......@@ -68,3 +68,5 @@ C66:ESIGNUM - ung
#{Default}
C67:Stub Daten Größe =
C68:Library Daten Größe =
C69:Nicht spezifizierter Fehler
C70:Unbekannter Fehler
......@@ -68,3 +68,5 @@ C66:ESIGNUM - incorrect signal number to signal() or raise()
#{Default}
C67:Stub data size =
C68:Library data size =
C69:unspecified error
C70:unknown error
......@@ -36,9 +36,8 @@ SharedLibrary SETL {TRUE}
AREA |Stub$$Code|, CODE, READONLY
[ Code_Destination = "RAM"
IMPORT |__RelocCode|, WEAK
|
[ Code_Destination <> "RAM"
IMPORT |_Shared_Lib_Module_SWI_Code|
; These in the RAM version are provided by the entry inclusions
......@@ -153,9 +152,13 @@ OS_Module EQU &1e
; so initialise always acquires it. Is this reasonable?
STMFD sp!, {r14}
MOV r9, r0 ; save 'copy statics' flag
[ Code_Destination = "RAM"
BL |__RelocCode|
]
; [ Code_Destination = "RAM"
LDR r0, =|__RelocCode| ; if __RelocCode is present, call it and
TEQ r0, #0 ; note the address of the relocation table
MOVEQ r0, #-1 ; in r8, else just set r8 to -1
BLNE __RelocCode
MOV r8, r0
; ]
MOV r4, #0
MOV r5, #-1
CMP r9, #0
......@@ -185,17 +188,42 @@ OS_Module EQU &1e
MOV r6, r6, ASR #10
MOVS r6, r6, ASL #16
[ Code_Destination = "RAM"
STMFD sp!, {r8}
SWI X:OR:Lib_Init + 2
LDMFD sp!, {r8} ; KJB - why preserve here???
|
; For ROM BL to the SWI code directly (yuck!)
STMFD r13!,{r11,r12}
STMFD r13!,{r8,r11,r12}
MOV r11,#2 ; SWI offset
MOV r12,#-3 ; A number liable to address exception if used
BL |_Shared_Lib_Module_SWI_Code|
LDMFD r13!,{r11,r12}
LDMFD r13!,{r8,r11,r12}
]
BVS %F99
; [ Code_Destination = "RAM"
; Chunk of code to relocate all the pointers in the data area
STMFD sp!, {r1-r5}
LDR r1, [r12]
CMP r1, #12
BEQ %F80
CMP r8, #0
BMI %F80
LDR r1, =|Image$$RO$$Base| ; r1 = pointer to code
LDR r2, =|Image$$RW$$Base| ; r2 = pointer to data template in module code area
ADD r3, r12, #fixedwssize ; r3 = pointer to our real data area (XXXX what if r0 was 0 on entry?? XXXX)
SUB r3, r3, r2 ; r3 = offset from data template to real data
ADD r1, r1, r3 ; r1 = code + data offset (odd, but saves work below)
70 LDR r4, [r8], #4 ; get a word from the relocation table
MOVS r4, r4, ASR #2
BMI %F80 ; if top bit set, it's the end of the table
BCC %B70 ; if bit 1 not set, it's not a data relocation
LDR r5, [r1, r4, LSL #2] ; read in the word to be relocated from the data area
ADD r5, r5, r3 ; add the magic offset
STR r5, [r1, r4, LSL #2] ; and put it back
B %B70
80 LDMFD sp!, {r1-r5}
[ Code_Destination = "RAM"
MOV r6, r6, ASL #16
CMP r6, #LibraryVersionNumber :SHL: 16
......@@ -314,7 +342,7 @@ GetRoundObjAsm SETS ""
$GetRoundObjAsm
|_rlib_entries_end|
AREA |Stub$$Data|, DATA
AREA |Stub$$Data|, DATA, NOINIT
|_k_data_start|
GET kernel.s.k_data
......
......@@ -22,6 +22,8 @@
#ifndef __hostsys_h
#define __hostsys_h
#include <stdio.h>
#undef MACHINE
#ifdef __arm
# ifndef __ARM
......@@ -71,6 +73,11 @@
# endif
#endif
extern char *_strerror(int n, char *v);
/* The same as strerror, except that if an error message must be constructed
* this is done into the array v.
*/
extern int _interrupts_off;
extern void _raise_stacked_interrupts(void);
extern void _postmortem(char *msg, int mflag);
......@@ -98,7 +105,7 @@ extern void _exit(int n);
typedef int FILEHANDLE;
#define TTYFILENAME ":tt"
extern int _osgbpb(int op, int fh, void *base, int len, int extra);
extern int _ttywrite(unsigned char *buf, unsigned int len, int flag);
extern int _ttywrite(const unsigned char *buf, unsigned int len, int flag);
extern int _ttyread(unsigned char *buff, int size, int flag);
extern double _ldfp(void *x);
extern void _stfp(double d, void *p);
......@@ -151,26 +158,64 @@ extern struct _svcwto _io_emsg; /* beware only 64 bytes thereof */
extern FILEHANDLE _sys_open(const char *name, int openmode);
/* openmode is a bitmap, whose bits have the following significance ... */
/* most correspond directly to the ANSI mode specification - the */
/* exception is OPEN_T, an extension which requests timestamp update. */
/* This is really a sop to implementation laziness: what is intended is */
/* that the timestamp should be updated if the file is written to or */
/* otherwise modified. But that is known only when the file is closed */
/* and RISC OS has no 'set timestamp given filehandle' operation and the */
/* name by which the file was opened may no longer be valid at the time */
/* of its close. */
#define OPEN_R 0
#define OPEN_W 4
#define OPEN_A 8
#define OPEN_B 1
#define OPEN_PLUS 2
#define OPEN_T 16
extern int _sys_close(FILEHANDLE fh);
/* result is 0 or an error indication */
extern int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode);
/* result is number of characters not written (ie non-0 denotes a */
/* failure of some sort) or a negative error indicator. */
extern int _sys_read(FILEHANDLE fh, unsigned char *buf, unsigned len, int mode);
/* result is number of characters not read (ie len - result _were_ read),*/
/* or negative to indicate error or EOF. */
/* _sys_iserror(result) distinguishes between the two possibilities. */
/* (Redundantly, since on EOF it is required that (result & ~0x80000000) */
/* is the number of characters unread). */
extern int _sys_istty(FILE *);
/* Return true if the argument file is connected to a terminal. */
/* Used to: provide default unbuffered behaviour (in the absence of a */
/* setbuf call). */
/* disallow seek */
extern int _sys_seek(FILEHANDLE fh, long pos);
/* Position the file at offset pos from its beginning. */
/* Result is >= 0 if OK, negative for an error. */
extern int _sys_ensure(FILEHANDLE fh);
/* Flush any OS buffers associated with fh, ensuring that the file is */
/* up to date on disc. (Only required if HOSTOS_NEEDSENSURE; see above) */
/* Result is >= 0 if OK, negative for an error. */
extern long _sys_flen(FILEHANDLE fh);
/* Return the current length of the file fh (or a negative error */
/* indicator). Required to convert fseek(, SEEK_END) into (, SEEK_START)*/
/* as required by _sys_seek. */
#ifdef __ARM
#define TTYHANDLE 0 /* maybe it is now time to switch these ... */
#define NONHANDLE (-1) /* ... two values */
#define _sys_istty_(fh) \
((fh) == TTYHANDLE)
#define _sys_seek_(fh, pos) \
((fh) == TTYHANDLE ? 0 : _kernel_osargs(1, fh, pos))
#define _sys_flen_(fh) \
_kernel_osargs(2, fh, 0)
#define _sys_write_(fh, buf, len, mode) \
((fh) == TTYHANDLE ? _ttywrite(buf,len,mode) : _osgbpb(2,fh,buf,len,0))
#define _sys_read_(fh, buf, len, mode) \
((fh) == TTYHANDLE ? _ttyread(buf,len,mode) : _osgbpb(4,fh,buf,len,0))
#define _sys_ensure_(fh) \
((fh) == TTYHANDLE ? 0 : _kernel_osargs(0xFF, fh, 0))
#define _sys_close_(fh) \
((fh) == TTYHANDLE ? 0 : _kernel_osfind(0, (char *)fh))
#define NONHANDLE (-1)
extern void _sys_tmpnam_(char *name, int sig);
/* Return the name for temporary file number sig in the buffer name. */
extern char *_hostos_error_string(int no, char *buf);
#endif
......
......@@ -12,5 +12,5 @@
; See the License for the specific language governing permissions and
; limitations under the License.
;
DCB "4.85 (19 Dec 1996)"
DCB "4.86 (25 Mar 1996)"
END
Markdown is supported
0% or