📄 cons_front.c
字号:
/* * Copyright (C) 1998, 1999, Jonathan Adams. * * 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 "cons_front.h"#include <eros/ReturnerKey.h>#include <eros/DiscrimKey.h>#include <domain/Runtime.h>const uint32_t __rt_stack_pointer = 0x41000;static uint8_t rcvData[EROS_PAGE_SIZE];static uint8_t snd_buffer[SIK_BUFSZ];#define KR_DISCRIM KR_APP(0)#define KR_CONS_IN KR_APP(1)#define KR_STASHEDKEY KR_APP(2)#define KR_TMP KR_APP(3)#define KR_CONSOLEKEY KR_APP(4)#define KR_SLEEPKEY KR_APP(5)#define KR_RETURNER KR_APP(6)#define KR_RK0 KR_ARG(0)#define KR_RK1 KR_ARG(1)#define KR_RK2 KR_ARG(2)uint32_t stash_wants_rdbytes;uint32_t stash_event_mask;uint32_t current_events;#define FLAG_EVENTS(evnts) (void)(current_events |= (evnts))#define STASH_READY() ((stash_event_mask & current_events))/* != 0 iff current_events and stash_event_mask have at least one 1 bit in the same place *//* * stash data structures */struct shared * const kdb_buf = (void *)SH_ADDR; /* points to the shared keyboard buffer */uint16_t notify_flag = 0;voidbcopy(const void *from, void *to, uint32_t len){ /* * standard EROS bcopy */ uint8_t *fp = (uint8_t *) from; uint8_t *tp = (uint8_t *) to; while(len--) *tp++ = *fp++;}intstrlen(const char *s){ register uint32_t count = 0; while (*s++) count++; return count;}voidinit (){ kdb_buf->timeoutChars = UINT32_MAX; kdb_buf->timeoutMsecs = 0u; stash_wants_rdbytes = 0u; stash_event_mask = 0u; return;}uint32_twriten(uint32_t n, const char *s){ /* * a simple mechanism for writing characters to the console. * */ Message msg; msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.snd_w1 = 0u; msg.snd_w2 = 0u; msg.snd_w3 = 0u; 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 = n; msg.rcv_len = 0; /* no data returned */ msg.snd_invKey = KR_CONSOLEKEY; msg.snd_code = 1; (void) CALL(&msg); return n; /* always send all characters. */}voidWrite(const char *s){ writen(strlen(s), s);}uint32_t diff(uint32_t head, uint32_t tail, uint32_t max, uint32_t full){ /* * return the number of bytes between "head" and "tail", given * a max bufsz of "max" */ if (full) return max; if (head == tail) return 0; if (head > tail) return (head - tail); else return (head + (max - tail)); }voidfork_cons_in ( ){ /* * we've been told that cons_in is available and waiting * for us to SEND it when the buffer starts to empty. * Now it's time to do it. */ Message msg; msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.snd_len = 0; msg.snd_w1 = 0u; msg.snd_w2 = 0u; msg.snd_w3 = 0u; msg.snd_invKey = KR_CONS_IN; msg.snd_code = RC_OK; (void) SEND(&msg); }uint32_tread_buf (uint32_t rdbytes, void *data){ /* * perform data xfer between shared keyboard buffer * and data buffer * * update our pointers in shared buf. * * return number of bytes transferred. */ uint32_t top; top = SIK_BUFSZ-kdb_buf->tail; if (top > rdbytes) /* no wrap */ { bcopy( &(kdb_buf->buf[kdb_buf->tail]), data, rdbytes); kdb_buf->tail += rdbytes; } else /* wrap buf */ { bcopy(&(kdb_buf->buf[kdb_buf->tail]), data, top ); kdb_buf->tail = 0; bcopy(&(kdb_buf->buf[kdb_buf->tail]), data + top , rdbytes - top); kdb_buf->tail += rdbytes - top; } if ((rdbytes) && (kdb_buf->full)) /* reset full ptr */ { kdb_buf->full = 0; if (notify_flag) fork_cons_in(); notify_flag = 0; } return rdbytes;}voidSetupStashReturn(Message *msg, uint32_t krStash){ uint32_t cur_head = kdb_buf->head; uint32_t bytes_avail = diff(cur_head, kdb_buf->tail, SIK_BUFSZ, kdb_buf->full); uint32_t toRead = stash_wants_rdbytes; if (bytes_avail < toRead) toRead = bytes_avail; if (!current_events) { kdprintf(KR_CONSOLEKEY, "Cons_front: SetupStashReturn called when no events were flagged!\n"); } msg->snd_len = read_buf(toRead, snd_buffer); msg->snd_data = snd_buffer; msg->snd_code = RC_OK; msg->snd_invKey = krStash; msg->snd_w1 = msg->snd_len; msg->snd_w2 = current_events; msg->snd_w3 = 0u; current_events = 0u; stash_wants_rdbytes = 0u; stash_event_mask = 0u; kdb_buf->wakeup = SIK_BUFSZ + 1;}voidSendStashAndPrepReturn(Message *msg, uint32_t krStash, uint32_t result){ uint32_t returnKey = msg->snd_invKey; SetupStashReturn(msg,krStash); SEND(msg); msg->snd_invKey = returnKey; msg->snd_code = result; msg->snd_key0 = KR_VOID; msg->snd_key1 = KR_VOID; msg->snd_key2 = KR_VOID; msg->snd_key3 = KR_VOID; msg->snd_w1 = 0u; msg->snd_w2 = 0u; msg->snd_w3 = 0u; msg->snd_len = 0; return;}uint32_t stash_reader (uint16_t keyNum, uint32_t rdbytes, uint32_t eventMask){ uint32_t obClass; /* * stash the reader's return key and number of bytes * * return 1 on succ; 0 if too many already stashed */ discrim_classify(KR_DISCRIM, keyNum, &obClass); if (obClass != Discrim_Class_Resume) return 0; /* not a resume key */ if (stash_event_mask != 0) { return 0; } else { copy_key_reg(KR_RETURNER, keyNum, KR_STASHEDKEY); copy_key_reg(KR_RETURNER, keyNum, KR_VOID); stash_wants_rdbytes = rdbytes; stash_event_mask = eventMask; /* reset the filled buffer event */ current_events &= ~(CharSrc_FilledBufferEvent); return 1; }}uint32_tverify_stashed_key(void){ uint32_t obClass; /* make sure the current stashed key is still valid */ discrim_classify(KR_DISCRIM, KR_STASHEDKEY, &obClass); if (obClass != Discrim_Class_Resume) { stash_wants_rdbytes = 0; stash_event_mask = 0; return 0; /* not a resume key */ } return 1;}voidset_wakeup (uint32_t rdbytes, uint32_t extra_bytes, uint32_t current_head){ /* * set the wakeup pointer to a position in the kbb_buffer. * never set the pointer further back. */#if 0 uint32_t current_wakeup = diff(kdb_buf->wakeup, current_head, SIK_BUFSZ, kdb_buf->full);#endif#if 0 DEBUG(unsorted) kprintf(KR_CONSOLEKEY, "cons_front: set_wakeup: kdb->wakeup %x curr_wakeup %x\n", kdb_buf->wakeup, current_wakeup); if (current_wakeup > extra_bytes) {#endif kdb_buf->wakeup = current_head + (rdbytes - extra_bytes); if (kdb_buf->wakeup >= SIK_BUFSZ) /* wrap buf */ kdb_buf->wakeup = kdb_buf->wakeup - SIK_BUFSZ;#if 0 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -