X-Git-Url: http://gitweb.hugovil.com/?a=blobdiff_plain;f=src%2Fcli%2Femuconsole.c;h=cbea820b89e89d175155ee76092576c105a02a64;hb=c7d14532b034286e990bc28c994fa20b23aca95a;hp=e88ca0d141d91ea0d00b70f9ee1a2c72d5c8def3;hpb=fd418e0f87d891d2cad0ce77e235a029487ab54e;p=emu8051.git diff --git a/src/cli/emuconsole.c b/src/cli/emuconsole.c index e88ca0d..cbea820 100644 --- a/src/cli/emuconsole.c +++ b/src/cli/emuconsole.c @@ -19,492 +19,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#define _GNU_SOURCE /* For getline() */ -#include #include -#include -#include /* For isblank, toupper() */ -#include "config.h" +#include +#include "config.h" #include "common.h" #include "cpu8051.h" -#include "reg8051.h" -#include "sfr.h" -#include "memory.h" -#include "timers.h" #include "options.h" #include "hexfile.h" -#include "keyboard.h" +#include "menu.h" +#include "parser.h" extern struct options_t options; -/* Capitalize all letters in buffer */ -static void -Capitalize(char *buffer) -{ - size_t k; - - for (k = 0; k < strlen(buffer); k++) - buffer[k] = toupper(buffer[k]); -} - -/* Remove leading spaces from string in buffer */ -static void -RemoveSpaces(char *buffer) -{ - size_t k = 0; - - while ((k < strlen(buffer)) && isblank(buffer[k])) - k++; - - if (k != 0) - strcpy(buffer, &buffer[k]); -} - -/* Disassemble NumberInst instructions at Address */ -static void -DisasmN(unsigned int Address, int NumberInst) -{ - char TextTmp[255]; - int Row; - - for (Row = 0; Row < NumberInst ; Row++) { - Address += cpu8051_Disasm(Address, TextTmp); - printf("%s\n", TextTmp); - - if (Address > 0xFFFF) - return; - } -} - -/* Disassemble 16 instructions at Address */ -static void -Disasm(char *Address, char *NumberInst) -{ - unsigned int MemAddress, NbInst; - - if ((strlen(Address) == 0) || (STREQ(Address, "PC"))) - MemAddress = cpu8051.pc; - else - MemAddress = Ascii2Hex(Address, strlen(Address)); - - if (strlen(NumberInst) == 0) - NumberInst = "10"; - NbInst = Ascii2Hex(NumberInst, strlen(NumberInst)); - DisasmN(MemAddress, NbInst); -} - -/* Set NewValue to Register */ -static void -SetRegister(char *Register, char *NewValue) -{ - if (STREQ(Register, "PC")) - cpu8051.pc = Ascii2Hex(NewValue, 4); - else if (STREQ(Register, "A")) - cpu8051_WriteD(_ACC_, Ascii2Hex(NewValue, 2)); - else if (STREQ(Register, "B")) - cpu8051_WriteD(_B_, Ascii2Hex(NewValue, 2)); - else if (STREQ(Register, "SP")) - cpu8051_WriteD(_SP_, Ascii2Hex(NewValue, 2)); - else { - printf("\nInvalid register name!\n"); - printf("Valid registers are A, B, PC and SP.\n"); - } -} - -/* Show CPU registers, one per line */ -static void -console_dump_sfr_registers_detailed(void) -{ - int k; - - for (k = 0; k < SFR_REGS; k++) { - struct regwin_infos_t *regwin_infos; - int val; - - regwin_infos = sfr_get_infos_from_row(k); - - printf("%s = ", regwin_infos->name); - - val = regwin_read(k); - if (regwin_infos->w == 2) - printf("$%02X", val); - else if (regwin_infos->w == 4) - printf("$%04X", val); - - printf("\n"); - } -} - -/* Show CPU registers, compact format */ -static void -console_dump_sfr_registers_compact(void) -{ - unsigned char PSW = cpu8051_ReadD(_PSW_); - int BankSelect = (PSW & 0x18); - - printf("---------------------------------------------------------------" - "-------\n"); - printf("| PC | SP | DPTR | ACC | B | PSW: CY AC F0 RS1 RS0 OV" - " - P |\n"); - printf("| %.4X | %.2X | %.4X | %.2X | %.2X |", cpu8051.pc, - cpu8051_ReadD(_SP_), - memory_sfr_read_dptr(), - cpu8051_ReadD(_ACC_), cpu8051_ReadD(_B_)); - printf(" %d %d %d %d %d %d %d %d |", - (PSW >> 7) & 1, (PSW >> 6) & 1, (PSW >> 5) & 1, (PSW >> 4) & 1, - (PSW >> 3) & 1, (PSW >> 2) & 1, (PSW >> 1) & 1, PSW & 1); - printf("\n"); - printf("---------------------------------------------------------------" - "-------\n"); - - printf("| TCON | TMOD | IE | IP | R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7" - " | |\n"); - printf("| %.2X | %.2X | %.2X | %.2X ", cpu8051_ReadD(_TCON_), - cpu8051_ReadD(_TMOD_), cpu8051_ReadD(_IE_), cpu8051_ReadD(_IP_)); - printf("| %.2X | %.2X | %.2X | %.2X ", - cpu8051_ReadD(BankSelect + _R0_), - cpu8051_ReadD(BankSelect + _R1_), - cpu8051_ReadD(BankSelect + _R2_), - cpu8051_ReadD(BankSelect + _R3_)); - printf("| %.2X | %.2X | %.2X | %.2X ", - cpu8051_ReadD(BankSelect + _R4_), - cpu8051_ReadD(BankSelect + _R5_), - cpu8051_ReadD(BankSelect + _R6_), - cpu8051_ReadD(BankSelect + _R7_)); - printf("| |\n"); - printf("---------------------------------------------------------------" - "-------\n"); - - printf("| General-purpose Timer: %08d |\n", gp_timer_read()); - printf("-----------------------------------\n"); -} - -/* Show CPU registers */ -static void -console_show_registers(void) -{ - if (options.stop_address != 0) - console_dump_sfr_registers_detailed(); - else - console_dump_sfr_registers_compact(); -} - -/* CPU reset and Console UI update */ -static void -console_reset(void) -{ - log_info("Resetting..."); - cpu8051_Reset(); - log_info("Done"); -} - -/* CPU exec and Console UI update */ -static void -console_exec(char *NumberInst) -{ - int NbInst = -1; /* -1 is infinity */ - - if (NumberInst) - if (strlen(NumberInst) != 0) - NbInst = Ascii2Hex(NumberInst, strlen(NumberInst)); - - InitUnixKB(); - - log_info("Program executing..."); - - cpu8051_run(NbInst, kbhit); - - if (kbhit()) { - (void) getch(); /* Flush key */ - log_info("Caught break signal!"); - } - - ResetUnixKB(); - console_show_registers(); - DisasmN(cpu8051.pc, 1); -} - -/* CPU trace and Console UI update */ -static void -console_trace() -{ - cpu8051_Exec(); - console_show_registers(); - DisasmN(cpu8051.pc, 1); -} - -/* EmuConsole main loop */ -static void -console_main(void) -{ - unsigned int Index; - char *line = NULL; - int QuitRequest = 0; - char prompt[] = "-> "; - - char *Title[] = { " *******************", - " * 8051 Emulator *", - " *******************", - "", 0 }; - - char *Menu[] = { - " Available commands, [ ] = options", - "", - " Set Breakpoint.............. SB [address]", - " Remove Breakpoint........... RB [address]", - " Display Breakpoint(s)....... DB", - " Dump External Data Memory... DE [address] [size]", - " Dump Internal Data Memory... DI [address] [size]", - " Dump Program Memory......... DP [address] [size]", - " Display Registers content... DR", - " Execute (Run)............... EM [number of instructions]", - " Help........................ H or ?", - " Modify External Data Memory. ME address value", - " Modify Internal Data Memory. MI address value", - " Modify Program Memory....... MP address value", - " Modify Register............. MR register value", - " Quit Emulator............... Q", - " Trace (step)................ T", - " Unassemble.................. U [address]" - " [number of instructions]", - " Reset processor............. Z", - " Reset general-purpose timer. ZT", 0 }; - - console_reset(); - - if (options.stop_address != 0) { - /* Automatically run program and stop at specified address. */ - console_exec(NULL); - QuitRequest = 1; - } else { - Index = 0; - while (Title[Index] != 0) - printf("%s\n", Title[Index++]); - - Index = 0; - while (Menu[Index] != 0) - printf("%s\n", Menu[Index++]); - - console_show_registers(); - } - - while (!QuitRequest) { - int slen; - size_t len = 0; - int rc; - char Command[256]; - char Args[256]; - char Parameter1[256]; - char Parameter2[256]; - - Parameter1[0] = '\0'; - Parameter2[0] = '\0'; - - printf("%s", prompt); - rc = getline(&line, &len, stdin); - if (rc < 0) - goto syntax_error; - - Capitalize(line); - RemoveSpaces(line); - - /* Strip trailing newline */ - slen = strlen(line); - if (line[slen - 1] == '\n') - line[slen - 1] = '\0'; - - /* Find command-arguments delimiter */ - for (Index = 0; Index < strlen(line); Index++) { - if (isblank(line[Index])) - break; - } - - if (strlen(line) == 0) { - /* Empty line, this is not an error. */ - continue; - } - - /* Keep only the Command part from the input line */ - memcpy(Command, &line[0], Index); - Command[Index] = '\0'; - - /* Keep only the arguments part from the input line */ - if (Index < strlen(line)) { - slen = strlen(line) - Index; - memcpy(Args, &line[Index + 1], slen); - } else { - slen = 0; - } - Args[slen] = '\0'; - RemoveSpaces(Args); - - /* Find multi-arguments delimiter */ - for (Index = 0; Index < strlen(Args); Index++) { - if (isblank(Args[Index])) - break; - } - - memcpy(Parameter1, &Args[0], Index); - Parameter1[Index] = '\0'; - - if (Index < strlen(Args)) { - slen = strlen(Args) - Index; - memcpy(Parameter2, &Args[Index + 1], slen); - } else { - slen = 0; - } - Parameter2[slen] = '\0'; - RemoveSpaces(Parameter2); - - if (strlen(Command) == 0) { - goto syntax_error; - continue; - } - - if ((strlen(Parameter1) > 4) || (strlen(Parameter2) > 4)) { - printf("Invalid Parameter Format!\n"); - continue; - } - - switch (Command[0]) { - case 'D': - if (STREQ(Command, "DB") && - (strlen(Parameter1) == 0)) - ShowBreakpoints(); - else if (STREQ(Command, "DE")) - DumpMem(Parameter1, Parameter2, EXT_MEM_ID); - else if (STREQ(Command, "DI")) - DumpMem(Parameter1, Parameter2, INT_MEM_ID); - else if (STREQ(Command, "DP")) { - if ((strlen(Parameter1) == 0)) - strcpy(Parameter1, "PC"); - DumpMem(Parameter1, Parameter2, PGM_MEM_ID); - } else if (STREQ(Command, "DR") && - (strlen(Parameter1) == 0)) - console_show_registers(); - else - goto syntax_error; - break; - case 'E': - if (STREQ(Command, "EM") && - (strlen(Parameter1) == 0)) - console_exec(NULL); - else if (STREQ(Command, "EM") && - (strlen(Parameter1) != 0)) - console_exec(Parameter1); - else - goto syntax_error; - break; - case 'H': - case '?': - if ((STREQ(Command, "H") || STREQ(Command, "?")) && - (strlen(Parameter1) == 0) && - (strlen(Parameter2) == 0)) { - Index = 0; - while (Menu[Index] != 0) - printf("%s\n", Menu[Index++]); - } else - goto syntax_error; - break; - case 'M': - if ((strlen(Parameter1) == 0) || - (strlen(Parameter2) == 0)) - printf("Missing Parameter!\n"); - else if (STREQ(Command, "ME")) { - unsigned int adresse = Ascii2Hex(Parameter1, 4); - unsigned char valeur = Ascii2Hex(Parameter2, 2); - memory_write8(EXT_MEM_ID, adresse, valeur); - } else if (STREQ(Command, "MI")) { - unsigned int adresse = Ascii2Hex(Parameter1, 2); - unsigned char valeur = Ascii2Hex(Parameter2, 2); - memory_write8(INT_MEM_ID, adresse, valeur); - } else if (STREQ(Command, "MP")) { - unsigned int adresse = Ascii2Hex(Parameter1, 4); - unsigned char valeur = Ascii2Hex(Parameter2, 2); - memory_write8(PGM_MEM_ID, adresse, valeur); - } else if (STREQ(Command, "MR")) - SetRegister(Parameter1, Parameter2); - else - goto syntax_error; - break; - case 'Q': - if (STREQ(Command, "Q") && (strlen(Parameter1) == 0) && - (strlen(Parameter2) == 0)) - QuitRequest = 1; - else - goto syntax_error; - break; - case 'R': - if (strlen(Parameter2) != 0) - goto TooMuchParameters; - if (STREQ(Command, "RB")) { - if (strlen(Parameter1) == 0) - ClearBreakpoint(cpu8051.pc); - else - ClearBreakpoint( - Ascii2Hex(Parameter1, 4)); - } else - goto syntax_error; - break; - case 'S': - if (strlen(Parameter2) != 0) - goto TooMuchParameters; - - if (STREQ(Command, "SB")) { - if (strlen(Parameter1) == 0) - SetBreakpoint(cpu8051.pc); - else - SetBreakpoint(Ascii2Hex(Parameter1, 4)); - } else - goto syntax_error; - break; - case 'T': - if ((strlen(Parameter1) != 0) || - (strlen(Parameter2) != 0)) - printf("Wrong Number of Parameters!\n"); - - if (STREQ(Command, "T")) - console_trace(); - else - goto syntax_error; - break; - case 'U': - if (STREQ(Command, "U")) - Disasm(Parameter1, Parameter2); - else - goto syntax_error; - break; - case 'Z': - if (STREQ(Command, "Z") && (strlen(Parameter1) == 0) && - (strlen(Parameter2) == 0)) - cpu8051_Reset(); - else if (STREQ(Command, "ZT") && - (strlen(Parameter1) == 0) && - (strlen(Parameter2) == 0)) - gp_timer_reset(); - else - goto syntax_error; - break; - case '\n': - break; - default: - goto syntax_error; - } - continue; - -syntax_error: - printf("Syntax Error!\n"); - continue; -TooMuchParameters: - printf("Wrong Number of Parameters!\n"); - continue; - } - - if (line) - free(line); -} - int main(int argc, char **argv) { @@ -520,9 +47,17 @@ main(int argc, char **argv) exit(1); } - console_main(); + console_reset(); - log_info("Terminate"); + if (options.stop_address != 0) { + /* Automatically run program and stop at specified address. */ + console_exec(-1); + } else { + menu_display_usage(); + console_show_registers(); + menu_prompt(); + yyparse(); + } return 0; }