/* tty3.c */ #include "asm.h" #include "display.h" #include "main.h" #include "process.h" #include "program.h" #include "registers.h" #include "scheduler.h" #include "string.h" #include "tty3.h" #include "types.h" bounded_filo IO_request_pids; bounded_fifo bfifo; bounded_fifo input; void init_UART() { tty->lcr.field.wls = 3; tty->ier.field.erbfi = 1; tty->mcr.field.out2 = 1; tty->ier.field.edssi = 1; bfifo.length = 0; input.length = 0; IO_request_pids.length = 0; } void handle_tty_input() { uint8_t ch; if (tty->lsr.field.dr) { ch = tty->rbr; if (ch == '\b') { if (input.length) { bfifo_put(&bfifo, CH_BACKSPACE); bfifo_put(&bfifo, CH_EMPTY); bfifo_put(&bfifo, CH_BACKSPACE); bfifo_backspace(&input); } else ch = ' '; } else if (ch == '\r') { bfifo_put(&bfifo, '\n'); bfifo_put(&bfifo, '\r'); // input to blocked processes char input_string[MAX_STR_LEN]; int i = 0; while (input.length) { input_string[i++] = bfifo_get(&input); } input_string[i] = '\0'; int index = bfilo_get(&IO_request_pids) - 1; string_memcpy(PCB_list[index].input, input_string); PCB_list[index].status = WAITING; // end input } else { bfifo_put(&bfifo, ch); bfifo_put(&input, ch); } } if (bfifo.length > 0) { ch = bfifo_get(&bfifo); while (!tty->lsr.field.thre) ; tty->thr = ch; tty->ier.field.etbei = (bfifo.length > 0); } } void print_string(char *str) { uint8_t ch; while (*str) { ch = *str++; while (!tty->lsr.field.thre); tty->thr = ch; if (ch == '\n') { while (!tty->lsr.field.thre); tty->thr = '\r'; } } } void print_int(int i) { char int_string[MAX_STR_LEN]; int_to_string(int_string, i); print_string(int_string); } void get_input(int pid) { PCB_list[pid - 1].status = BLOCKED; bfilo_put(&IO_request_pids, pid); hold(pid); } void display_word(char s[MAX_STR_LEN]) { int str_len = str_length(s); malta->ledbar.reg = 0xFF; int i; for (i = 0; i < 8; i++) { if (s[i] && i < str_len) { malta->asciipos[i].value = s[i]; } else { malta->asciipos[i].value = CH_EMPTY; } } } void bfifo_backspace(bounded_fifo* bfifo) { if (bfifo->length) { bfifo->buf[(bfifo->length)--] = CH_EMPTY; } } void bfifo_put(bounded_fifo* bfifo, uint8_t ch) { if (bfifo->length < FIFO_SIZE) { bfifo->buf[(bfifo->length)++] = ch; } } void bfilo_put(bounded_filo* bfilo, uint8_t ch) { if (bfilo->length < FILO_SIZE) { bfilo->buf[(bfilo->length)++] = ch; } } uint8_t bfifo_get(bounded_fifo* bfifo) { if (bfifo->length) { uint8_t ch; bfifo->length--; ch = bfifo->buf[0]; int i; for (i = 0; i < bfifo->length; i++) { bfifo->buf[i] = bfifo->buf[i + 1]; } return ch; } else { return 0; } } uint8_t bfilo_get(bounded_filo* bfilo) { if (bfilo->length) { uint8_t ch = bfilo->buf[bfilo->length - 1]; bfilo->length--; return ch; } else { return 0; } } void erase_IO_entries(int pid) { int i; for (i = 0; i < IO_request_pids.length; i++) { if (IO_request_pids.buf[i] == pid) { shift_IO(i); } } } void shift_IO(int i) { IO_request_pids.length--; for ( ; i < IO_request_pids.length; i++) { IO_request_pids.buf[i] = IO_request_pids.buf[i + 1]; } } void print_IO() { int i; for (i = 0; i < FILO_SIZE; i++) { print_int(IO_request_pids.buf[i]); if (i == IO_request_pids.length) { print_string("|"); } else { print_string(" "); } } NEWLINE; }