#include #define CMDMAX 256 #define YOTSH_ENABLED(n) ((ctrlflag)&(n)) #define YOTSH_AUTOCOPY 0x0001 #define YOTSH_COUNTER 0x0002 #define YOTSH_VERBOSE 0x0004 int main(){ /*---------------------*/ int cmdcount; int ctrlflag; /*---------------------*/ char cmdline[CMDMAX]; char argcopy[CMDMAX]; char *cp1, *cp2; bool end; unsigned out, loadaddr; extern int char_vga_cursor_x; extern int char_vga_cursor_y; XYCOORD screenxy; /*env_def(&ENV_END-sizeof(int),&ENV_START-&ENV_END-sizeof(int));*/ env_def(&ctrlflag, 2*2); if(!env_load()){ ctrlflag = YOTSH_COUNTER; cmdcount = 0; putstr("YOT OS shell [Real mode]\r\n\r\n"); } cmdline[0] = '\0'; while(++cmdcount){ if(YOTSH_ENABLED(YOTSH_COUNTER)){ putint(cmdcount); putstr(":"); }else{ putstr("<"); } putstr("yotsh> "); if(YOTSH_ENABLED(YOTSH_AUTOCOPY)){ yotrl(cmdline, cmdline, CMDMAX - 1, CHV_COLORPAIR(CHV_COLOR_LIGHT_CYAN, CHV_COLOR_BLACK)); }else{ yotrl(cmdline, NULL, CMDMAX - 1, CHV_COLORPAIR(CHV_COLOR_LIGHT_RED, CHV_COLOR_BLACK)); } if(YOTSH_ENABLED(YOTSH_VERBOSE)){ putstr("+ "); putstr(cmdline); putstr("\r\n"); } for(cp1=cmdline, cp2=argcopy; *cp1 != ' '&& *cp1 != '\0'; cp1++, cp2++){ *cp2 = *cp1; } end = ((*cp1 == '\0') ? true : false); *cp2 = '\0'; if(!strcmp(argcopy, "set")){ cp2 = cmdline + 3; if(!end){ cp2++; } for(; *cp2 == ' '; cp2++); if((*cp2 == '\0' || *cp2 == '?') || !strcmp(cp2, "help")){ putstr("YOTSH function list:" "\r\n autocopy " "Automatically copy last command to input buffer" "\r\n counter " "Enable counter in command prompt" "\r\n verbose " "Print the input line as they are read" "\r\n"); }else if(!strcmp(cp2, "autocopy")){ ctrlflag |= YOTSH_AUTOCOPY; }else if(!strcmp(cp2, "counter")){ ctrlflag |= YOTSH_COUNTER; }else if(!strcmp(cp2, "verbose")){ ctrlflag |= YOTSH_VERBOSE; }else{ putstr("yotsh: set: invalid function name `"); putstr(cp2); putstr("\'\r\n"); putstr("Type `set help\' for more information.\r\n"); } }else if(!strcmp(argcopy, "unset")){ cp2 = cmdline + 5; if(!end){ cp2++; } for(; *cp2 == ' '; cp2++); if((*cp2 == '\0' || *cp2 == '?') || !strcmp(cp2, "help")){ putstr("Please type `set help\' to get function list\r\n"); }else if(!strcmp(cp2, "autocopy")){ ctrlflag &= ~(YOTSH_AUTOCOPY); }else if(!strcmp(cp2, "counter")){ ctrlflag &= ~(YOTSH_COUNTER); }else if(!strcmp(cp2, "verbose")){ ctrlflag &= ~(YOTSH_VERBOSE); }else{ putstr("yotsh: unset: invalid function name `"); putstr(cp2); putstr("\'\r\n"); } }else if(!strcmp(argcopy, "read")){ cp2 = cmdline + 4; if(!end){ cp2++; } if(*cp2 == '\0'){ putstr("yotsh: read: too few argument\r\n"); continue; } for(; *cp2 == ' '; cp2++); if(strtos(cp2, &out)){ cp1 = out; out = *cp1 & 0x00ff; putstr("decimal="); putint(out); putstr(", hexadecimal="); putcharhex(out); putstr("\r\n"); }else{ putstr("yotsh: read: invalid address `"); putstr(cp2); putstr("\'\r\n"); } }else if(!strcmp(argcopy, "tinyload") || !strcmp(argcopy, "easyload")){ cp2 = cmdline + 8; if(!end){ cp2++; } for(; *cp2 == ' '; cp2++); if(*cp2 == '\0'){ putstr("yotsh: tinyload: too few argument\r\n"); continue; } if(strtos(cp2, &out)){ out &= 0x0fff; out |= 0x1000; return out; }else{ putstr("yotsh: read: invalid address `"); putstr(cp2); putstr("\'\r\n"); } }else if(!strcmp(argcopy, "load")){ cp2 = cmdline + 4; if(!end){ cp2++; } for(; *cp2 == ' '; cp2++); if(*cp2 == '\0'){ putstr("yotsh: load: two argument required\r\n"); continue; } loadaddr = 0; for(cp1=cp2; *cp1 != ' ' && *cp1 != '\0'; cp1++); for(; *cp1 == ' '; cp1++); if(*cp1 == '\0'){ putstr("yotsh: load: two argument required\r\n"); continue; } for(; *cp1 == ' '; cp1++); *(cp1 - 1) = '\0'; if(strtos(cp2, &out)){ out &= 0x0fff; loadaddr |= out; }else{ putstr("yotsh: load: invalid address `"); putstr(cp2); putstr("\'\r\n"); continue; } if(strtos(cp1, &out)){ if(out & 0x0003){ out = (out >> 2) + 1; }else{ out = (out >> 2); } loadaddr |= (out << 12); *(cp1 - 1) = ' '; return loadaddr; }else{ putstr("yotsh: load: invalid number `"); putstr(cp1); putstr("\'\r\n"); continue; } }else if(!strcmp(argcopy, "halt") || !strcmp(argcopy, "poweroff") || !strcmp(argcopy, "shutdown")){ asm "int 0x50"; }else if(!strcmp(argcopy, "reboot")){ cp1 = 0; asm "int 0x51"; }else if(!strcmp(argcopy, "reload") || !strcmp(argcopy, "reload2") || !strcmp(argcopy, "yot16") || !strcmp(argcopy, "yotrm")){ cp1=0; return 0; }else if(!strcmp(argcopy, "yot32") || !strcmp(argcopy, "yotpm") || !strcmp(argcopy, "protect")){ putstr( "WARNING: You cannot run any real mode program " "unless rebooting!\r\n" "Do you want to switch to protected mode ? [no] "); yotrl(cmdline, NULL, 3, 7); if(!strcmp(cmdline, "yes")){ return (3 << 12) | 101; }else{ if(cmdline[0] == 'y' || cmdline[0] == 'Y'){ putstr("You should type `yes\'.\r\n"); }else{ putstr("Not confirmed.\r\n"); } } }else if(!strcmp(argcopy, "loadgarbage")){ cp1=0; return 74; }else if(!strcmp(argcopy, "loadnull")){ cp1=0; return 57920; }else if(!strcmp(argcopy, "loadstupid")){ cp1=0; return 73; }else if(!strcmp(argcopy, "clear") || !strcmp(argcopy, "cls")){ chv_clear(); chv_reset_cursor(); char_vga_tobios(); }else if(!strcmp(argcopy, "help") || argcopy[0] == '?'){ cp2 = cmdline + 4; if(!end){ cp2++; } for(; *cp2 == ' '; cp2++); if(!strcmp(cp2, "set")){ putstr("Syntax: set [option]\r\n" "Type `set help\' to display option list.\r\n"); }else if(!strcmp(cp2, "unset")){ putstr("Syntax: unset [option]\r\n" "Type `set help\' to display option list.\r\n"); }else if(!strcmp(cp2, "read")){ putstr("Syntax: read MEM_ADDR\r\n"); }else if(!strcmp(cp2, "tinyload")){ putstr("Syntax: tinyload SECTOR_OFFSET\r\n"); }else if(!strcmp(cp2, "load")){ putstr("Syntax: load SECTOR_OFFSET SIZE_KB\r\n"); }else if(!strcmp(cp2, "clear")){ putstr("Syntax: clear\r\n"); }else if(!strcmp(cp2, "halt")){ putstr("Syntax: halt\r\n"); }else if(!strcmp(cp2, "reboot")){ putstr("Syntax: reboot\r\n"); }else if(!strcmp(cp2, "reload")){ putstr("Syntax: reload\r\n"); }else if(!strcmp(cp2, "yot32")){ putstr("Syntax: yot32\r\n"); }else if(!strcmp(cp2, "loadgarbage") || !strcmp(cp2, "loadstupid") || !strcmp(cp2, "loadnull")){ putstr(" You can try to guess it!\r\n" " YYYYY\r\n" " OOOOO\r\n" " TTTTT\r\n" " SSSSS\r\n" " HHHHH\r\n" " \r\n"); }else{ putstr("YOTSH command list:" "\r\n set " "Enable shell function" "\r\n unset " "Disable shell function" "\r\n read " "Load a byte from memory and display it" "\r\n tinyload " "Load a tiny program from disk (< 4KiB)" "\r\n load " "Load a program" "\r\n clear " "Clear the screen" "\r\n halt " "Shutdown the computer" "\r\n reboot " "Reboot the computer" "\r\n reload " "Reload the shell" "\r\n yot32 " "Switch to protected mode" "\r\n loadgarbage " "Display some garbage to screen" "\r\n loadstupid " "Infinite loop" "\r\n loadnull " "Load a non-existent program" "\r\n" "You can press F12 to terminate a running program.\r\n"); } }else if(*argcopy != '\0'){ putstr("yotsh: invalid command `"); putstr(argcopy); putstr("\'\r\n"); putstr("Type `help\' for more information.\r\n"); }else{ cmdcount--; } } return 0; }