⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttyin.c

📁 C++ 编写的EROS RTOS
💻 C
字号:
/* * Copyright (C) 1998, 1999, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "linedisc.h"const uint32_t __rt_stack_pages = 0; const uint32_t __rt_stack_pointer = 0x21000;#define KR_VOID 0#define KR_CONSOLEKEY 9#define KR_SLEEPKEY 10#define KR_KBDKEY 8#define KR_LINEDISC 7#define KR_KEYBITS 11#define KR_TTYSEG 5#define KR_LINESEG 6#define KR_TMP 4#define KR_RK0     12#define KR_RK1     13#define KR_RK2     14#define KR_RETURN  15struct shared *kdb_buf;intstrlen(const char *s){  const char *send = s;  while (*send)    send++;  return send - s;}voidWrite(const char *s){     Message msg;     msg.snd_key0 = KR_VOID;     msg.snd_key1 = KR_VOID;     msg.snd_key2 = KR_VOID;     msg.snd_key3 = KR_VOID;     msg.rcv_key0 = KR_VOID;     msg.rcv_key1 = KR_VOID;     msg.rcv_key2 = KR_VOID;     msg.rcv_key3 = KR_VOID;     msg.snd_data = (uint8_t *) s;     msg.snd_len = strlen(s);	/* omit trailing null! */     msg.rcv_len = 0;		/* no data returned */     msg.snd_invKey = KR_CONSOLEKEY;     msg.snd_code = 1;     (void) CALL(&msg);}voidSleep(uint32_t nsec){     Message msg;     uint64_t ms = nsec;     ms *= 1000;     msg.snd_key0 = KR_VOID;     msg.snd_key1 = KR_VOID;     msg.snd_key2 = KR_VOID;     msg.snd_key3 = KR_VOID;     msg.rcv_key0 = KR_VOID;     msg.rcv_key1 = KR_VOID;     msg.rcv_key2 = KR_VOID;     msg.rcv_key3 = KR_VOID;     msg.snd_data = &ms;     msg.snd_len = sizeof(ms);	/* omit trailing null! */     msg.rcv_len = 0;		/* no data returned */     msg.snd_invKey = KR_SLEEPKEY;     msg.snd_code = 1;     (void) CALL(&msg);}chargetc(){     Message msg;     char chr[2];			/* chr + 0 */     uint16_t Result;     uint32_t bytes = 1;     msg.snd_key0 = KR_VOID;     msg.snd_key1 = KR_VOID;     msg.snd_key2 = KR_VOID;     msg.snd_key3 = KR_VOID;     msg.rcv_key0 = KR_VOID;     msg.rcv_key1 = KR_VOID;     msg.rcv_key2 = KR_VOID;     msg.rcv_key3 = KR_VOID;     msg.snd_len = sizeof(bytes);     msg.snd_data = &bytes;     msg.rcv_len = sizeof(chr);     msg.rcv_data = chr;     msg.snd_invKey = KR_KBDKEY;     msg.snd_code = 0;     Result = CALL(&msg);     if (Result != RC_OK)	  return 0;     else	  return (*chr);		/* return the character */}voidcook (uint16_t chr)		{     Message msg;     msg.snd_key0 = KR_VOID;     msg.snd_key1 = KR_VOID;     msg.snd_key2 = KR_VOID;     msg.snd_key3 = KR_VOID;     msg.rcv_key0 = KR_VOID;     msg.rcv_key1 = KR_VOID;     msg.rcv_key2 = KR_VOID;     msg.rcv_key3 = KR_VOID;     msg.snd_len = 1;     msg.snd_data = &chr;     msg.rcv_len = 0;     msg.snd_invKey = KR_LINEDISC;     msg.snd_code = LD_WRITE;     CALL(&msg); }uint32_tnotifyLine (uint32_t oc)		{     /*      * tell line disp to wake us up when it starts to       * empty the buffer      */     Message msg;     msg.snd_key0 = KR_VOID;     msg.snd_key1 = KR_VOID;     msg.snd_key2 = KR_VOID;     msg.snd_key3 = KR_VOID;     msg.rcv_key0 = KR_VOID;     msg.rcv_key1 = KR_VOID;     msg.rcv_key2 = KR_VOID;     msg.rcv_key3 = KR_VOID;     msg.snd_len = 0;		/* no data to send */     msg.rcv_len = 0;		/* no data to send */     msg.snd_invKey = KR_LINEDISC;     msg.snd_code = oc;#ifdef DEBUG     kprintf(KR_CONSOLEKEY, "TTYin: CALLING linedisc with oc %x...\n",	     msg.snd_code);  #endif     CALL(&msg);     if (msg.rcv_code == RC_OK)       return 1;     else       return 0;}void_exit (){     /*      * tell line disp to wake us up when it starts to       * empty the buffer      */     Message msg;     msg.snd_key0 = KR_VOID;     msg.snd_key1 = KR_VOID;     msg.snd_key2 = KR_VOID;     msg.snd_key3 = KR_VOID;     msg.rcv_key0 = KR_VOID;     msg.rcv_key1 = KR_VOID;     msg.rcv_key2 = KR_VOID;     msg.rcv_key3 = KR_VOID;     msg.snd_len = 0;		/* no data to send */     msg.rcv_len = 0;		/* no data to send */     msg.snd_invKey = KR_VOID;     msg.snd_code = 1;#ifdef DEBUG     kprintf(KR_CONSOLEKEY, "TTYin: RETURNING to zero number key\n");#endif     RETURN(&msg); }voidtty_init (){     /*      * intialize various data structs      */     /* copy domain1's 10th slot, put into tmp */     node_copy(KR_LINESEG, SH_SLOT, KR_TMP);      /* copy tmp into our 10th slot */     node_swap(KR_TTYSEG, SH_SLOT, KR_TMP, KR_VOID);        kdb_buf = (struct shared *) SH_ADDR;     kdb_buf->mode = COOKED;		/* set to COOKED by default -- arbitrary */     kdb_buf->wakeup = SIK_BUFSZ+1;	/* set wakeup out of bounds */     kdb_buf->head = 0;     kdb_buf->tail = 0;     kdb_buf->full = 0;  }uint16_taddtoBuf (char chr){     /*      * this will be slighly less trivial once      * we support more than one chr at a time      */       if (kdb_buf->full)	  return 0;       kdb_buf->buf[kdb_buf->head] = chr;     if (kdb_buf->head == (SIK_BUFSZ - 1))	  kdb_buf->head = 0;     else	  kdb_buf->head++;     if (kdb_buf->head == kdb_buf->tail)	  kdb_buf->full = 1;     return 1;}intProcessRequest(Message *msg){     /*      * a nice feature of the new IPC logic is that      * multiple domains can be set running from the start.      *      * proceed to call the kdb key in an infinite loop      * notify linedisp of changes in buffer as we reach critical      * (wakeup) points      *      */     char Result;     uint32_t added;		/* flag to indicate whether a char				   made it into the buffer */#ifdef DEBUG     kprintf(KR_CONSOLEKEY, "TTYin: starting...\n");  #endif     tty_init();			/* intialize various data structs */#ifdef DEBUG     kprintf(KR_CONSOLEKEY, "TTYin: init done.  starting loop...\n");  #endif     for ( ; ; )     {#ifdef DEBUG	  kprintf(KR_CONSOLEKEY, "TTYin: looping...\n");  #endif	  /*	   * currently getc() returns a single character	   * someday we will be dealing with multiples with early termination	   *	   * that is, what we'd like to do is move the COOKED mode	   * early \n termination logic into the kernel	   *	   * until then, COOKED mode is going to be slower than	   * it could be	   */	  Result = getc();		/* try to read a character */#ifdef DEBUG	  kprintf(KR_CONSOLEKEY, "TTYin: Result from getc is %x\n",Result);#endif	  if (kdb_buf->mode == COOKED)	       cook (Result);		/* contacts the linedisp domain, not console */#ifdef DEBUG	  kprintf (KR_CONSOLEKEY, "TTYin: attempting to addtoBuf...\n");#endif	  added = 0;	  /*	   * FIX: Alright you bonehead, this code is bloody	   * unreadable -- do something about it	   */	  	  while (!added)	  {	       	    if ((kdb_buf->mode == RAW) ||		((kdb_buf->mode == COOKED) && (Result > US)))	      {		if (addtoBuf(Result))		  {		    added = 1;#ifdef DEBUG		    kprintf (KR_CONSOLEKEY, "TTYin: addtoBuf h %x t %x w %x....\n",			     kdb_buf->head, kdb_buf->tail, kdb_buf->wakeup);#endif		    if ((kdb_buf->head == kdb_buf->wakeup) &&			(kdb_buf->mode == RAW))		      {#ifdef DEBUG			kprintf (KR_CONSOLEKEY, "TTYin: Wakeup linedisc...\n");#endif			notifyLine(LD_WAKEUP);		      }		  }		else			/* AddtoBuf failed; buffer full */		  {#ifdef DEBUG		    kprintf (KR_CONSOLEKEY, "TTYin: Buffer full.  Waiting...\n");#endif		    /*		     * we want to return to the available state		     * so that the linedisc can wake us up when 		     * the buffer is empty again.		     *		     * first we need to tell linedisc about the		     * situation; so we will CALL linedisc then		     * return to ZERO.  		     *		     * When linedisc wakes us up it will do a fork 		     * on us.		     */		    		    		    if (notifyLine(LD_NOTIFY))		      _exit();#ifdef DEBUG		    kprintf (KR_CONSOLEKEY, "TTYin: Back from the dead...\n");#endif  		  }	      }	    else if (Result == 13)	      {#ifdef DEBUG			kprintf (KR_CONSOLEKEY, "TTYin: Wakeup linedisc...\n");#endif			notifyLine(LD_WAKEUP);			added = 1;	      }	    else	      added = 1;	  }     }     return 1;}static uint8_t rcvData[EROS_PAGE_SIZE];voidmain(){     Message msg;     msg.snd_invKey = KR_VOID;     msg.snd_key0 = KR_VOID;     msg.snd_key1 = KR_VOID;     msg.snd_key2 = KR_VOID;     msg.snd_key3 = KR_VOID;     msg.snd_data = 0;     msg.snd_len = 0;     msg.snd_code = 0;     msg.snd_w1 = 0;     msg.snd_w2 = 0;     msg.snd_w3 = 0;          msg.rcv_key0 = KR_RK0;     msg.rcv_key1 = KR_RK1;     msg.rcv_key2 = KR_RK2;     msg.rcv_key3 = KR_RETURN;     msg.rcv_data = rcvData;     msg.rcv_code = 0;     msg.rcv_w1 = 0;     msg.rcv_w2 = 0;     msg.rcv_w3 = 0;          msg.rcv_len = EROS_PAGE_SIZE;     msg.snd_invKey = KR_RETURN;     ProcessRequest(&msg);     }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -