mescc: Add fsync.
[mes.git] / mlibc.c
1 /* -*-comment-start: "//";comment-end:""-*-
2  * Mes --- Maxwell Equations of Software
3  * Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
4  *
5  * This file is part of Mes.
6  *
7  * Mes is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or (at
10  * your option) any later version.
11  *
12  * Mes is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #if __GNUC__
22 int g_stdin = 0;
23 typedef long size_t;
24 void *malloc (size_t i);
25 int open (char const *s, int mode);
26 int read (int fd, void* buf, size_t n);
27 void write (int fd, char const* s, int n);
28
29 #define O_RDONLY 0
30 #define INT_MIN -2147483648
31 #define INT_MAX 2147483647
32 #define EOF -1
33 #define STDIN 0
34 #define STDOUT 1
35 #define STDERR 2
36
37 void
38 exit (int code)
39 {
40   asm (
41        "movl %0,%%ebx\n\t"
42        "movl $1,%%eax\n\t"
43        "int  $0x80"
44        : // no outputs "=" (r)
45        : "" (code)
46        );
47   // not reached
48   exit (0);
49 }
50
51 char const*
52 getenv (char const* p)
53 {
54   return 0;
55 }
56
57 int
58 read (int fd, void* buf, size_t n)
59 {
60   int r;
61   //syscall (SYS_write, fd, s, n));
62   asm (
63        "movl %1,%%ebx\n\t"
64        "movl %2,%%ecx\n\t"
65        "movl %3,%%edx\n\t"
66
67        "movl $0x3,%%eax\n\t"
68        "int  $0x80\n\t"
69
70        "mov %%eax,%0\n\t"
71        : "=r" (r)
72        : "" (fd), "" (buf), "" (n)
73        : "eax", "ebx", "ecx", "edx"
74        );
75   return r;
76 }
77
78 int
79 open (char const *s, int mode)
80 {
81   int r;
82   //syscall (SYS_open, mode));
83   asm (
84        "mov %1,%%ebx\n\t"
85        "mov %2,%%ecx\n\t"
86        "mov $0x5,%%eax\n\t"
87        "int $0x80\n\t"
88        "mov %%eax,%0\n\t"
89        : "=r" (r)
90        : "" (s), "" (mode)
91        : "eax", "ebx", "ecx"
92        );
93   return r;
94 }
95
96 int puts (char const*);
97 char const* itoa (int);
98
99 void
100 write (int fd, char const* s, int n)
101 {
102   int r;
103   //syscall (SYS_write, fd, s, n));
104   asm (
105        "mov %0,%%ebx\n\t"
106        "mov %1,%%ecx\n\t"
107        "mov %2,%%edx\n\t"
108
109        "mov $0x4, %%eax\n\t"
110        "int $0x80\n\t"
111        : // no outputs "=" (r)
112        : "" (fd), "" (s), "" (n)
113        : "eax", "ebx", "ecx", "edx"
114        );
115 }
116
117 int
118 fsync (int fd)
119 {
120   int r;
121   //syscall (SYS_fsync, fd));
122   asm (
123        "mov %1,%%ebx\n\t"
124
125        "mov $0x76, %%eax\n\t"
126        "int $0x80\n\t"
127        "mov %%eax,%0\n\t"
128        : "=r" (r)
129        : "" (fd)
130        : "eax", "ebx"
131        );
132   return r;
133 }
134
135 void *
136 brk (void *p)
137 {
138   void *r;
139   asm (
140        "mov %1,%%ebx\n\t"
141
142        "mov $0x2d,%%eax\n\t"
143        "int $0x80\n\t"
144
145        "mov %%eax,%0\n\t"
146        : "=r" (r)
147        : "" (p)
148        : "eax", "ebx"
149        );
150   return r;
151 }
152
153 int
154 putc (int c, int fd)
155 {
156   write (fd, (char*)&c, 1);
157   return 0;
158 }
159
160 int
161 putchar (int c)
162 {
163   write (STDOUT, (char*)&c, 1);
164   return 0;
165 }
166
167 void *g_malloc_base = 0;
168
169 void *
170 malloc (size_t size)
171 {
172   void *p = brk (0);
173   if (!g_malloc_base) g_malloc_base = p;
174   brk (p+size);
175   return p;
176 }
177
178 void *
179 realloc (void *p, size_t size)
180 {
181   (void)p;
182   brk (g_malloc_base + size);
183   return g_malloc_base;
184 }
185
186 void
187 free (void *p)
188 {
189   int *n = (int*)p-1;
190   //munmap ((void*)p, *n);
191 }
192
193 size_t
194 strlen (char const* s)
195 {
196   int i = 0;
197   while (s[i]) i++;
198   return i;
199 }
200
201 int
202 strcmp (char const* a, char const* b)
203 {
204   while (*a && *b && *a == *b) {a++;b++;}
205   return *a - *b;
206 }
207
208 int
209 eputs (char const* s)
210 {
211   int i = strlen (s);
212   write (STDERR, s, i);
213   return 0;
214 }
215
216 int
217 fputs (char const* s, int fd)
218 {
219   int i = strlen (s);
220   write (fd, s, i);
221   return 0;
222 }
223
224 int
225 puts (char const* s)
226 {
227   int i = strlen (s);
228   write (STDOUT, s, i);
229   return 0;
230 }
231
232 void
233 assert_fail (char* s)
234 {
235   eputs ("assert fail: ");
236   eputs (s);
237   eputs ("\n");
238   *((int*)0) = 0;
239 }
240
241 #define assert(x) ((x) ? (void)0 : assert_fail (#x))
242
243
244 int ungetc_char = -1;
245 char ungetc_buf[2];
246
247 int
248 getchar ()
249 {
250   char c;
251   int i;
252   if (ungetc_char == -1)
253     {
254       int r = read (g_stdin, &c, 1);
255       if (r < 1) return -1;
256       i = c;
257     }
258   else
259     i = ungetc_buf[ungetc_char--];
260
261   if (i < 0) i += 256;
262
263   return i;
264 }
265
266 int
267 ungetc (int c, int fd)
268 {
269   assert (ungetc_char < 2);
270   ungetc_buf[++ungetc_char] = c;
271   return c;
272 }
273
274 char itoa_buf[10];
275
276 char const*
277 itoa (int x)
278 {
279   //static char itoa_buf[10];
280   //char *p = buf+9;
281   char *p = itoa_buf;
282   p += 9;
283   *p-- = 0;
284
285   //int sign = x < 0;
286   int sign;
287   sign = x < 0;
288   if (sign)
289     x = -x;
290
291   do
292     {
293       *p-- = '0' + (x % 10);
294       x = x / 10;
295     } while (x);
296
297   if (sign)
298     *p-- = '-';
299
300   return p+1;
301 }
302
303 int
304 isdigit (int c)
305 {
306   return (c>='0') && (c<='9');
307 }
308 #endif