/* term.c - terminal routines */ #include #include "ascii8x8.h" static int row = 0; static int col = 0; static unsigned *scr_ptr; static int serial = 0; unsigned long ByteSwap(unsigned long val) // http://www.ethernut.de/en/documents/arm-inline-asm.html { asm volatile ( "eor r3, %1, %1, ror #16\n\t" "bic r3, r3, #0x00FF0000\n\t" "mov %0, %1, ror #8\n\t" "eor %0, %0, r3, lsr #8" : "=r" (val) : "0"(val) : "r3" ); return val; } int setIOmode(int cmd){ if (cmd == -1) return serial; serial = cmd; // set mode: 0 == console , 1 == rs232 return cmd; } int drawchar(int ch){ int i; for(i=0;i<8;++i){ scr_ptr = (unsigned*)( SCREEN_BASE_ADDRESS + 0x500*row + 4*col +i*0xA0); *scr_ptr = ByteSwap(lowerascii[ch*8 + i]); } ++col; return 0; } void scrollregion(int rows, int cursorX, int cursorY){ // number of rows to scroll - usually 1 int y,w; memmove(SCREEN_BASE_ADDRESS, SCREEN_BASE_ADDRESS + 1280*rows, 38400 - 1280*rows); for(y=29-rows+1;y<=29;++y){ // clear the scrolled in region row = y; col = 0; for(w=0;w<40;++w)drawchar(0x20); } row = cursorY; col = cursorX; // move cursor when done } int drawstring(char *s){ int i; i = 0; char ch; if(serial){ log_rs232_v(s); return 1; } while( (char) *(s+i) != '\0'){ ch = (char) *(s+i); if(ch == '\n' || ch == '\r'){ ++row; col = 0; if (row > 29) scrollregion(1,0,29); ++i; continue; } drawchar((int) ch); if(col >= 40){ ++row; col = 0; } if (row > 29) scrollregion(1,0,29); ++i; } return i; } void ShowCursor(void) { char pa[0x104]; if(serial == 1){ getcwd(pa,0x101); log_rs232_v(pa); log_rs232_v(">"); return ; } else { drawchar(0x1f); --col; } } unsigned getch(void) { event *e; unsigned now, skey; e = (event*)EVENT; do { idle(); //((void(*)(void))0xd0078128)(); now = e->timestamp; TCC_Task_Sleep(0x3); // give OS 3 ticks timer updates, ... } while (e->type != 0x8 || e->timestamp == now ); skey = e->ascii | e->key << 8 | e->modifier << 16; return skey; } int rs232_gets(char *buffer, int bufsize){ int index = 0; int ch; char pckey[4]; pckey[0] = '\0';pckey[1] = '\0';pckey[2] = '\0';pckey[3] = '\0'; do{ ch = SDC_Data_Ready(log_rs232_param2_); if (ch == 0 ){ TCC_Task_Sleep(2); continue; // nothing pressed } ch = SDC_Get_Char(log_rs232_param2_); if(ch == 0xd || ch == 0xa){ // return or enter pressed log_rs232_v("\n"); // echo the key break; } if(ch == 0x8 && index > 0){ // backspace pressed --index; *(buffer + index) = '\0'; log_rs232_v("\b"); // move cursor back for rubout log_rs232_v(" "); // rubout unwanted char log_rs232_v("\b"); // move cursor back continue; } *(buffer + index) = (char)ch; ++index; pckey[0] = (char)ch; log_rs232_v(pckey); // echo the key }while(index < bufsize); if (index >= bufsize) index = bufsize-1; // should be == *(buffer + index) = '\0'; return index; } char *gets(char *buf) { char ch,chs[4]; int len, key; buf[0] = '\0'; chs[0] = '\0'; chs[1] = '\0'; chs[2] = '\0'; chs[3] = '\0'; if(serial){ rs232_gets(buf,40); return buf; } do { key = getch(); ch = (char)(key & 0xff); if (ch == '\b' && strlen(buf) > 0 && col > 0){ // backspace - rubout drawstring("\x01"); // rubout the cursor --col; --col; drawstring("\x1F"); // overwrite the character with the cursor --col; len = strlen(buf); buf[--len] = '\0'; // delete last char in buffer continue; } if ((int)ch >= 0x20 && (int)ch < 0x80){ // printable ascii char chs[0] = ch; drawchar((int) ch); // echo the key if(col >= 40){ ++row; col = 0; } if (row > 29) scrollregion(1,0,29); // scroll screen one line if necessary ShowCursor(); strcat(buf,chs); continue; } } while (ch != '\n' && ch != '\r' && ch != (char)27); // return key(10) or Enter key(13) or ESC key(27) drawchar(0x20); // erase cursor col = 0; ++row; // advance to next line becuse of carriage return if (row > 29){ scrollregion(1,0,29); // scroll one line up if cursor past bottom of screen } ShowCursor(); if ((int)ch ==27){strcat(buf,"\x1b");} // concat ESC if pressed return buf; } void clearscreen(void){ memset(SCREEN_BASE_ADDRESS, 0xFF, SCREEN_BYTES_SIZE); row = 0; col = 0; ShowCursor(); }