zasm assembly compiler support next instruction (jmp; inc; mov 32bit, 32bit; hlt...
[ZeXOS.git] / kernel / arch / i386 / syscall.c
blob3c27df8cac71d772e19ca0f9e9fbb4dc8e6c9405
1 /*
2 * ZeX/OS
3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <system.h>
22 #include <arch/io.h>
23 #include <string.h>
24 #include <tty.h>
25 #include <proc.h>
26 #include <net/socket.h>
27 #include <file.h>
28 #include <signal.h>
29 #include <module.h>
30 #include <rs232.h>
32 int sattrib = 0x0F;
34 extern task_t *_curr_task;
35 void sys_exit (struct regs *r)
37 proc_t *proc = proc_find (_curr_task);
39 if (!proc)
40 return;
42 if (proc->task != _curr_task)
43 return;
45 if (proc) {
46 task_t *task = proc->tty->task;
48 proc->pid = 0;
50 if (int_disable ())
51 longjmp (task->state, 1);
52 else
53 while (1)
54 schedule ();
58 void sys_getch (struct regs *r)
60 proc_t *proc = proc_find (_curr_task);
62 if (!proc)
63 return;
65 if (proc->task != _curr_task)
66 return;
68 if (proc->tty != currtty)
69 return;
71 unsigned char c = (unsigned char) getkey ();
73 if (c)
74 setkey (0);
76 r->eax = (unsigned) &c;
78 /*unsigned char *where;
79 unsigned char *memptr = (unsigned char *) 0x9045;
80 where = memptr;
81 *where = c;*/
84 extern unsigned long timer_ticks;
85 void sys_sleep (struct regs *r)
87 unsigned long timer_start = timer_ticks + ((unsigned) r->ebx * 1000);
89 while (timer_start > timer_ticks)
90 schedule ();
93 void sys_putch (struct regs *r)
95 proc_t *proc = proc_find (_curr_task);
97 if (!proc)
98 return;
100 if (proc->task != _curr_task)
101 return;
103 if (proc->tty != currtty)
104 return;
106 tty_putnch (proc->tty, r->ebx);
109 void sys_color (struct regs *r)
111 settextcolor (r->ebx, r->ecx);
115 void sys_cls (struct regs *r)
117 proc_t *proc = proc_find (_curr_task);
119 if (!proc)
120 return;
122 if (proc->task != _curr_task)
123 return;
125 if (proc->tty != currtty)
126 return;
128 /* NOTE: Why we should disable interrupts ? Nobody know, but works better */
129 if (int_disable ()) {
130 tty_cls (proc->tty);
131 int_enable ();
135 extern unsigned char scancode;
136 void sys_getkey (struct regs *r)
138 proc_t *proc = proc_find (_curr_task);
140 if (!proc)
141 return;
143 if (proc->task != _curr_task)
144 return;
146 if (proc->tty != currtty)
147 return;
149 unsigned char c = (unsigned char) scancode;
151 scancode = 0;
153 r->eax = (unsigned) &c;
156 void sys_gotoxy (struct regs *r)
158 gotoxy (r->ebx, r->ecx);
161 void sys_fork (struct regs *r)
163 unsigned short *where;
164 unsigned char c = (unsigned char) fork ();
166 unsigned short *memptr = (unsigned short *) 0x9000;
167 where = memptr;
168 *where = c;
171 void sys_schedule (struct regs *r)
173 schedule ();
176 extern kbd_quaue kbd_q;
177 void sys_write (struct regs *r)
179 unsigned len = r->ecx;
180 unsigned fd = r->edx;
182 unsigned char *buf = (unsigned char *) r->ebx;
184 if (!buf)
185 return;
187 //kprintf ("#buf: 0x%x / '%s'\n", buf, buf);
189 /*char buf[len+1];
190 if (!memcpy_to_user (&buf, (char *) r->ebx, len))
191 return;*/
193 int ret = 0;
195 proc_t *proc = 0;
196 char *mem = 0;
198 switch (fd) {
199 case 0:
200 proc = proc_find (_curr_task);
202 if (!proc)
203 return;
205 if (proc->task != _curr_task)
206 return;
208 //if (buf >= proc->data && buf < (proc->data+proc->data_off)) {
209 // kprintf ("Je to staticky retezec :) - 0x%x - '%s'\n", buf+proc->code, buf+proc->code);
212 mem = (char *) buf;//vmem_proc_check (proc, buf);
214 //if (proc->tty != currtty)
215 // return;
217 //printf ("data: 0x%x | 0x%x\n", buf, proc->data);
219 //if (!memtest_data (buf, (void *) proc->data, proc->data_off))
220 tty_write (proc->tty, (char *) mem, len);
221 //else {
222 // tty_write (proc->tty, (char *) buf+proc->code, len);
224 ret = len;
225 //timer_wait (5000);
227 break;
228 case 1:
229 proc = proc_find (_curr_task);
231 if (!proc)
232 return;
234 if (proc->task != _curr_task)
235 return;
237 if (len > KBD_MAX_QUAUE)
238 len = KBD_MAX_QUAUE;
240 mem = (char *) buf;
242 int i = 0;
243 for (i = len; i >= 0; i --) {
244 setkey (buf[i]);
245 kbd_q.state[kbd_q.p] = 1; // down
246 kbd_q.p ++;
249 mem[len] = '\0';
251 ret = len;
252 break;
253 default:
254 mem = (char *) buf; //vmem_proc_check (proc, buf);
255 //printf ("hehe: 0x%x / '%s' len: %d\n", mem, mem, len);
256 ret = write (fd, (char *) mem, len);
257 break;
260 int *where;
261 int *memptr = (int *) 0x9000;
262 where = memptr;
263 *where = ret;
265 //printf ("yeah, sys_write: '%d' '%s' '0x%x'\n", len, buf, buf);
268 void sys_socket (struct regs *r)
270 int ret = socket (r->ebx, r->ecx, r->edx);
272 int *where;
273 int *memptr = (int *) 0x9000;
274 where = memptr;
275 *where = ret;
278 void sys_connect (struct regs *r)
280 sockaddr *addr = (sockaddr *) r->ebx;
282 int ret = connect (r->ecx, addr, r->edx);
284 int *where;
285 int *memptr = (int *) 0x9000;
286 where = memptr;
287 *where = ret;
290 void sys_malloc (struct regs *r)
292 r->eax = (unsigned) kmalloc ((int) r->ebx);
294 DPRINT ("malloc (): 0x%x\n", r->eax);
297 void sys_send (struct regs *r)
299 /* char msg[r->edx+1];
300 if (!memcpy_to_user (&msg, (char *) r->ebx, r->edx))
301 return;*/
303 int ret = send ((int) r->ecx, (char *) r->ebx, (unsigned) r->edx, 0);
305 int *where;
306 int *memptr = (int *) 0x9040;
307 where = memptr;
308 *where = ret;
311 void sys_recv (struct regs *r)
313 unsigned char *msg = (unsigned char *) r->ebx;
315 int ret = recv ((int) r->ecx, (char *) msg, (unsigned) r->edx, 0);
317 //printf ("recv> r->ebx: %d, r->edx: %u, ret: %d\n", (int) r->ecx, (unsigned) r->edx, ret);
319 int *where;
320 int *memptr = (int *) 0x9030;
321 where = memptr;
322 *where = ret;
325 void sys_close (struct regs *r)
327 close (r->ebx);
330 void sys_open (struct regs *r)
332 unsigned char *pathname = (unsigned char *) r->ebx;
334 int ret = open ((char *) pathname, (unsigned) r->ecx);
336 // printf ("%d = sys_open (%s, %u)\n", ret, (char *) pathname, (unsigned) r->ecx);
338 int *where;
339 int *memptr = (int *) 0x9000;
340 where = memptr;
341 *where = ret;
344 void sys_pcspk (struct regs *r)
346 dev_t *dev = dev_find ("/dev/pcspk");
348 if (dev)
349 dev->handler (DEV_ACT_PLAY, (unsigned) r->ebx);
352 void sys_usleep (struct regs *r)
354 usleep ((unsigned) r->ebx);
357 void sys_read (struct regs *r)
359 unsigned fd = r->ecx;
360 unsigned len = r->edx;
362 unsigned char *buf = (unsigned char *) r->ebx;
364 int ret = 0;
366 proc_t *proc = 0;
368 switch (fd) {
369 case 0:
370 break;
371 case 1:
372 proc = proc_find (_curr_task);
374 if (!proc)
375 break;
377 if (proc->task != _curr_task)
378 break;
380 //if (proc->tty != currtty)
381 // return;
383 ret = tty_read (proc->tty, (char *) buf, len);
384 break;
385 default:
386 ret = read (fd, (char *) buf, len);
387 break;
390 int *where;
391 int *memptr = (int *) 0x9000;
392 where = memptr;
393 *where = ret;
396 void sys_time (struct regs *r)
398 r->eax = (unsigned) rtc_getcurrtime ();
401 void sys_system (struct regs *r)
403 unsigned char *cmd = (unsigned char *) r->ebx;
405 command_parser ((char *) cmd, strlen (cmd));
408 void sys_chdir (struct regs *r)
410 unsigned char *dir = (unsigned char *) r->ebx;
412 cd ((char *) dir);
415 void sys_getdir (struct regs *r)
417 r->eax = (unsigned) vfs_dirent ();
420 void sys_procarg (struct regs *r)
422 proc_t *proc = proc_find (_curr_task);
424 if (!proc)
425 return;
427 if (proc->task != _curr_task)
428 return;
430 switch (r->ecx) {
431 case 0:
432 r->eax = (unsigned) proc->argv;
433 break;
434 case 1:
435 r->eax = (unsigned) proc->argc;
436 break;
437 default:
438 r->eax = 0;
442 void sys_signal (struct regs *r)
444 signal (r->ebx, (sighandler_t) r->ecx);
447 void sys_mount (struct regs *r)
449 partition_t *p = partition_find ((char *) r->ebx);
451 if (p) {
452 mount (p, "", (char *) r->ecx);
453 r->eax = 1;
454 } else
455 r->eax = 0;
458 void sys_kputs (struct regs *r)
460 int_disable ();
462 module_t *kmod = module_find (_curr_task);
464 if (!kmod)
465 return;
467 if (kmod->task != _curr_task)
468 return;
470 unsigned char *buf = (unsigned char *) r->ebx;
471 kprintf (buf);
473 //kprintf ("yeah, sys_kputs: '%s' '0x%x'\n", buf, buf);
475 int_enable ();
478 void sys_bind (struct regs *r)
480 int ret = bind (r->ecx, (sockaddr *) r->ebx, r->edx);
482 int *where;
483 int *memptr = (int *) 0x9000;
484 where = memptr;
485 *where = ret;
488 void sys_listen (struct regs *r)
490 int ret = listen (r->ebx, r->ecx);
492 int *where;
493 int *memptr = (int *) 0x9000;
494 where = memptr;
495 *where = ret;
498 void sys_accept (struct regs *r)
500 int ret = accept (r->ecx, r->ebx, r->edx);
502 int *where;
503 int *memptr = (int *) 0x9000;
504 where = memptr;
505 *where = ret;
508 void sys_fcntl (struct regs *r)
510 int ret = fcntl (r->ebx, r->ecx, r->edx);
512 int *where;
513 int *memptr = (int *) 0x9000;
514 where = memptr;
515 *where = ret;
518 extern unsigned char vgagui;
519 void sys_gvgafb (struct regs *r)
521 kprintf ("vgagui: %d\n", vgagui);
522 if (vgagui != 2) {
523 sys_exit (r);
524 return;
527 r->eax = (unsigned) init_vgafb ();
530 void sys_gcls (struct regs *r)
532 //gcls (r->ebx);
535 void sys_gpixel (struct regs *r)
537 //gpixel (r->ebx, r->ecx, r->edx);
540 void sys_rs232read (struct regs *r)
542 char *where;
543 char *memptr = (char *) 0x9000;
544 where = memptr;
545 *where = rs232_read ();
548 void sys_rs232write (struct regs *r)
550 rs232_write ((char) r->ebx);
553 void sys_gttyexit (struct regs *r)
555 proc_t *proc = proc_find (_curr_task);
557 if (!proc)
558 return;
560 if (proc->task != _curr_task)
561 return;
563 tty_change (proc->tty);
566 void sys_gexit (struct regs *r)
568 gexit ();
571 extern unsigned char vgagui;
572 extern tty_t *gtty;
573 void sys_gttyinit (struct regs *r)
575 gtty_init ();
577 if (!gtty)
578 return;
580 r->eax = (unsigned) &gtty->screen;
583 void sys_mkdir (struct regs *r)
585 unsigned char *dir = (unsigned char *) r->ebx;
587 mkdir ((char *) dir);
590 void sys_free (struct regs *r)
592 kfree ((void *) r->ebx);
594 DPRINT ("free (): 0x%x\n", r->ebx);
597 void sys_realloc (struct regs *r)
599 r->eax = (unsigned) krealloc ((void *) r->ebx, (size_t) r->ecx);
601 DPRINT ("realloc (): 0x%x\n", r->eax);
604 void sys_gethostbyname (struct regs *r)
606 char *buf = (char *) r->ebx;
608 if (!buf) {
609 r->eax = 0;
610 return;
613 r->eax = (unsigned) gethostbyname (buf);
616 void sys_procmap (struct regs *r)
618 proc_t *proc = proc_find (_curr_task);
620 if (!proc)
621 return;
623 if (proc->task != _curr_task)
624 return;
626 proc_vmem_map (proc);
629 void sys_sendto (struct regs *r)
631 /* HACK: bleeh, there is problem with fourth argument,
632 so we need to use another way to getting address */
633 unsigned *addr = (unsigned *) 0x9020;
635 sockaddr_in *to = (sockaddr_in *) *addr;
637 int ret = sendto ((int) r->ecx, (char *) r->ebx, (unsigned) r->edx, 0, to, 0);
639 int *where;
640 int *memptr = (int *) 0x9000;
641 where = memptr;
642 *where = ret;
645 void sys_recvfrom (struct regs *r)
647 unsigned char *msg = (unsigned char *) r->ebx;
649 /* HACK: bleeh, there is problem with fourth argument,
650 so we need to use another way to getting address */
651 unsigned *addr = (unsigned *) 0x9010;
653 sockaddr_in *from = (sockaddr_in *) *addr;
655 int ret = recvfrom ((int) r->ecx, (char *) msg, (unsigned) r->edx, 0, from, 0);
657 int *where;
658 int *memptr = (int *) 0x9000;
659 where = memptr;
660 *where = ret;
663 void sys_getchar (struct regs *r)
665 proc_t *proc = proc_find (_curr_task);
667 int i = 1;
668 unsigned char s = '\n';
670 /* non-blocking mode */
671 if (stdin->flags & O_NONBLOCK) {
672 if (!proc)
673 return;
675 if (proc->task != _curr_task)
676 return;
678 if (proc->tty != currtty)
679 return;
681 char c = (char) getkey ();
683 if (!c) {
684 c = -1;
685 r->eax = (int) &c;
686 return;
689 tty_write (proc->tty, &c, 1);
691 r->eax = (int) &c;
693 return;
696 /* blocking - clasical mode */
697 while (1) {
698 if (!proc)
699 return;
701 if (proc->task != _curr_task)
702 return;
704 if (proc->tty != currtty)
705 return;
707 unsigned char c = (unsigned char) getkey ();
709 if (c) {
710 setkey (0);
712 if (i > 0 && c != '\b')
713 tty_write (proc->tty, &c, 1);
715 if (c == '\n')
716 break;
717 else if (i == 1)
718 s = c;
720 if (c == '\b') {
721 if (i > 1) {
722 i --;
723 tty_write (proc->tty, "\b", 1);
725 } else
726 i ++;
730 r->eax = (unsigned) &s;
733 void syscall_handler (struct regs *r)
735 switch (r->eax) {
736 case 1:
737 return sys_exit (r);
738 case 2:
739 return sys_getch (r);
740 case 3:
741 return sys_sleep (r);
742 case 4:
743 return sys_putch (r);
744 case 5:
745 return sys_color (r);
746 case 6:
747 return sys_cls (r);
748 case 7:
749 return sys_getkey (r);
750 case 8:
751 return sys_gotoxy (r);
752 case 9:
753 return sys_fork (r);
754 case 10:
755 return sys_schedule (r);
756 case 11:
757 return sys_write (r);
758 case 12:
759 return sys_socket (r);
760 case 13:
761 return sys_connect (r);
762 case 14:
763 return sys_malloc (r);
764 case 15:
765 return sys_send (r);
766 case 16:
767 return sys_recv (r);
768 case 17:
769 return sys_close (r);
770 case 18:
771 return sys_open (r);
772 case 19:
773 return sys_pcspk (r);
774 case 20:
775 return sys_usleep (r);
776 case 21:
777 return sys_read (r);
778 case 22:
779 return sys_time (r);
780 case 23:
781 return sys_system (r);
782 case 24:
783 return sys_chdir (r);
784 case 25:
785 return sys_getdir (r);
786 case 26:
787 return sys_procarg (r);
788 case 27:
789 return sys_signal (r);
790 case 28:
791 return sys_mount (r);
792 case 29:
793 return sys_kputs (r);
794 case 30:
795 return sys_bind (r);
796 case 31:
797 return sys_listen (r);
798 case 32:
799 return sys_accept (r);
800 case 33:
801 return sys_fcntl (r);
802 case 34:
803 return sys_gvgafb (r);
804 case 35:
805 return sys_gcls (r);
806 case 36:
807 return sys_gpixel (r);
808 case 37:
809 return sys_rs232read (r);
810 case 38:
811 return sys_rs232write (r);
812 case 39:
813 return sys_gttyexit (r);
814 case 40:
815 return sys_gexit (r);
816 case 41:
817 return sys_gttyinit (r);
818 case 42:
819 return sys_mkdir (r);
820 case 43:
821 return sys_free (r);
822 case 44:
823 return sys_realloc (r);
824 case 45:
825 return sys_gethostbyname (r);
826 case 46:
827 return sys_procmap (r);
828 case 47:
829 return sys_sendto (r);
830 case 48:
831 return sys_recvfrom (r);
832 case 49:
833 return sys_getchar (r);