完成第一次实验
This commit is contained in:
parent
8b4ccf9bd1
commit
cd4dff43d2
@ -33,8 +33,8 @@ void
|
|||||||
clock_init(void) {
|
clock_init(void) {
|
||||||
// set 8253 timer-chip
|
// set 8253 timer-chip
|
||||||
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
|
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
|
||||||
outb(IO_TIMER1, TIMER_DIV(100) % 256);
|
outb(IO_TIMER1, TIMER_DIV(1000) % 256);
|
||||||
outb(IO_TIMER1, TIMER_DIV(100) / 256);
|
outb(IO_TIMER1, TIMER_DIV(1000) / 256);
|
||||||
|
|
||||||
// initialize time counter 'ticks' to zero
|
// initialize time counter 'ticks' to zero
|
||||||
ticks = 0;
|
ticks = 0;
|
||||||
|
@ -149,7 +149,12 @@ struct trapframe switchk2u, *switchu2k;
|
|||||||
/* trap_dispatch - dispatch based on what type of trap occurred */
|
/* trap_dispatch - dispatch based on what type of trap occurred */
|
||||||
static void
|
static void
|
||||||
trap_dispatch(struct trapframe *tf) {
|
trap_dispatch(struct trapframe *tf) {
|
||||||
char c;
|
volatile char c;
|
||||||
|
// 有限状态机?
|
||||||
|
static enum {STARTED=0, STOPPED=1, WAITING_FOR_INPUT, READY_TO_OUTPUT} state = STOPPED;
|
||||||
|
// 唉不能long long,看来很有可能会溢出啊
|
||||||
|
static long milliseconds = 0;
|
||||||
|
static enum {COUNTDOWN=-1, COUNTUP=1} mode = COUNTUP;
|
||||||
|
|
||||||
switch (tf->tf_trapno) {
|
switch (tf->tf_trapno) {
|
||||||
case IRQ_OFFSET + IRQ_TIMER:
|
case IRQ_OFFSET + IRQ_TIMER:
|
||||||
@ -159,10 +164,27 @@ trap_dispatch(struct trapframe *tf) {
|
|||||||
* (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks().
|
* (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks().
|
||||||
* (3) Too Simple? Yes, I think so!
|
* (3) Too Simple? Yes, I think so!
|
||||||
*/
|
*/
|
||||||
ticks ++;
|
switch (state) {
|
||||||
if (ticks % TICK_NUM == 0) {
|
case STARTED:
|
||||||
print_ticks();
|
milliseconds += mode;
|
||||||
|
// 当时间倒计时到0时转成停止状态
|
||||||
|
// 而正计时加了mode之后至少为1所以不会转换状态
|
||||||
|
// 使用小于等于0而不是等于0是为了防止万一出现异常导致小于0的情况
|
||||||
|
state = READY_TO_OUTPUT * (milliseconds <= 0); // 为了减少分支才写成这样
|
||||||
|
break;
|
||||||
|
case READY_TO_OUTPUT:
|
||||||
|
state = STOPPED;
|
||||||
|
mode = COUNTUP;
|
||||||
|
if (milliseconds < 0) milliseconds = 0; // 防止出现异常小于0
|
||||||
|
cprintf(MSG_COUNTDOWN_STOP);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
ticks ++;
|
||||||
|
// if (ticks % TICK_NUM == 0) {
|
||||||
|
// print_ticks();
|
||||||
|
// }
|
||||||
break;
|
break;
|
||||||
case IRQ_OFFSET + IRQ_COM1:
|
case IRQ_OFFSET + IRQ_COM1:
|
||||||
c = cons_getc();
|
c = cons_getc();
|
||||||
@ -170,7 +192,58 @@ trap_dispatch(struct trapframe *tf) {
|
|||||||
break;
|
break;
|
||||||
case IRQ_OFFSET + IRQ_KBD:
|
case IRQ_OFFSET + IRQ_KBD:
|
||||||
c = cons_getc();
|
c = cons_getc();
|
||||||
cprintf("kbd [%03d] %c\n", c, c);
|
if (state == WAITING_FOR_INPUT) {
|
||||||
|
long seconds = milliseconds / 1000;
|
||||||
|
// if (c != '\0') cprintf("%c", c);
|
||||||
|
// 如果是正在输入状态,此时不能键入字母或其他各种字符
|
||||||
|
// 在这里不能直接break不然就直接跳出中断处理程序了
|
||||||
|
// 所以用c=0来防止执行后面的转换状态
|
||||||
|
if (c == '\b' || c == '\n' || ('0' <= c && c <= '9')) {
|
||||||
|
cprintf("%c", c);
|
||||||
|
} else {
|
||||||
|
c = '\0';
|
||||||
|
}
|
||||||
|
if (c == '\b') {
|
||||||
|
seconds /= 10;
|
||||||
|
}
|
||||||
|
if ('0' <= c && c <= '9') {
|
||||||
|
seconds *= 10;
|
||||||
|
seconds += c - '0';
|
||||||
|
}
|
||||||
|
milliseconds = seconds * 1000;
|
||||||
|
if (c == '\n') {
|
||||||
|
state = STARTED;
|
||||||
|
}
|
||||||
|
c = '\0'; // 如果是正在输入状态,此时不能根据字母转换状态
|
||||||
|
}
|
||||||
|
switch (c) {
|
||||||
|
case 'a':
|
||||||
|
mode = COUNTUP;
|
||||||
|
cprintf(MSG_COUNTUP_START);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
mode = COUNTDOWN;
|
||||||
|
cprintf(MSG_COUNTDOWN_START);
|
||||||
|
state = WAITING_FOR_INPUT;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
case 'c':
|
||||||
|
state = STARTED;
|
||||||
|
cprintf(MSG_START);
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
state = STOPPED;
|
||||||
|
cprintf(MSG_PAUSE, milliseconds / 1000, milliseconds % 1000);
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
state = STOPPED;
|
||||||
|
cprintf(MSG_STOP, milliseconds / 1000, milliseconds % 1000);
|
||||||
|
milliseconds = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// cprintf("kbd [%03d] %c\n", c, c);
|
||||||
break;
|
break;
|
||||||
//LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes.
|
//LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes.
|
||||||
case T_SWITCH_TOU:
|
case T_SWITCH_TOU:
|
||||||
|
@ -47,6 +47,27 @@
|
|||||||
#define T_SWITCH_TOU 120 // user/kernel switch
|
#define T_SWITCH_TOU 120 // user/kernel switch
|
||||||
#define T_SWITCH_TOK 121 // user/kernel switch
|
#define T_SWITCH_TOK 121 // user/kernel switch
|
||||||
|
|
||||||
|
#define ENGLISH
|
||||||
|
#ifndef ENGLISH
|
||||||
|
|
||||||
|
#define MSG_COUNTDOWN_STOP "倒计时到0了,停止,转到正计时。\n"
|
||||||
|
#define MSG_COUNTUP_START "正计时\n"
|
||||||
|
#define MSG_COUNTDOWN_START "倒计时,请输入秒数:\n"
|
||||||
|
#define MSG_START "开始\n"
|
||||||
|
#define MSG_PAUSE "暂停,当前秒数:%d.%d\n"
|
||||||
|
#define MSG_STOP "停止,当前秒数:%d.%d\n"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define MSG_COUNTDOWN_STOP "Coutdown to 0, stopped, to be countup.\n"
|
||||||
|
#define MSG_COUNTUP_START "Countup\n"
|
||||||
|
#define MSG_COUNTDOWN_START "Countdown, please input seconds:\n"
|
||||||
|
#define MSG_START "Started\n"
|
||||||
|
#define MSG_PAUSE "Paused, current seconds: %d.%d\n"
|
||||||
|
#define MSG_STOP "Stopped, current seconds: %d.%d\n"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* registers as pushed by pushal */
|
/* registers as pushed by pushal */
|
||||||
struct pushregs {
|
struct pushregs {
|
||||||
uint32_t reg_edi;
|
uint32_t reg_edi;
|
||||||
|
Loading…
Reference in New Issue
Block a user