📄 console.cpp
字号:
//-----------------------------------------------------------------------------
//
// console.c -- Seiko Epson Standard console handling support.
//
// Copyright (c) 2002 Epson Research and Development, Inc.
// All rights reserved.
//
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include "console.h"
#include "helper.h"
#define ESC 0x1B
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
static char ConPromptStringSaved[256];
static UInt32 ConBaseAddr;
#define ConContext (ConBaseAddr==0)
static ConReadFunc ConReadMem;
static ConWriteFunc ConWriteMem;
static ConScriptFunc ConScript;
static UInt32 ConDumpStartAddr[2];
static UInt32 ConDumpLen[2];
static int ConDumpUnitSize[2];
static UInt32 ConFillStartAddr[2];
static UInt32 ConFillLen[2];
static int ConFillUnitSize[2];
static UInt32 ConReadStartAddr[2];
static int ConReadUnitSize[2];
static UInt32 ConSearchStartAddr[2];
static UInt32 ConSearchLen[2];
static int ConSearchUnitSize[2];
static UInt32 ConWriteStartAddr[2];
static UInt32 ConWriteLen[2];
static int ConWriteUnitSize[2];
// Local workhorse functions.
static void ConPrintCharData( UInt32* pData, int UnitSize );
static char* ConDoPrompt( char *Str, int Size, ConHookFunc cb, Boolean UseHistory );
void InitConsole( void )
//
// Initialize all global variables because some embedded systems don't when
// the application is invoked the second time. Because of this problem, do
// NOT declare static variables within a function scope -- always use globals.
//
{
ConPromptStringSaved[0] = '\0';
ConBaseAddr = 0;
ConReadMem = ConReadTradMemory;
ConWriteMem = ConWriteTradMemory;
ConScript = NULL;
ConDumpStartAddr[0] = ConDumpStartAddr[1] = 0x0;
ConDumpLen[0] = ConDumpLen[1] = 0x100;
ConDumpUnitSize[0] = ConDumpUnitSize[1] = 1;
ConFillStartAddr[0] = ConFillStartAddr[1] = 0x0;
ConFillLen[0] = ConFillLen[1] = 0;
ConFillUnitSize[0] = ConFillUnitSize[1] = 1;
ConReadStartAddr[0] = ConReadStartAddr[1] = 0x0;
ConReadUnitSize[0] = ConReadUnitSize[1] = 1;
ConSearchStartAddr[0] = ConSearchStartAddr[1] = 0x0;
ConSearchLen[0] = ConSearchLen[1] = 0;
ConSearchUnitSize[0] = ConSearchUnitSize[1] = 1;
ConWriteStartAddr[0] = ConWriteStartAddr[1] = 0x0;
ConWriteLen[0] = ConWriteLen[1] = 0;
ConWriteUnitSize[0] = ConWriteUnitSize[1] = 1;
}
UInt32 atoxl( char *str )
{
UInt32 RetVal=0;
int i;
for ( i=0; ; i++ )
{
if ( str[i] == '\0' )
break;
switch ( str[i] )
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
RetVal = (RetVal<<4) + (str[i]-'0');
break;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
RetVal = (RetVal<<4) + (str[i]-'A') + 10;
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
RetVal = (RetVal<<4) + (str[i]-'a') + 10;
break;
}
}
return RetVal;
}
char* ConPrompt( char *Str, int Size, ConHookFunc cb )
{
return ConDoPrompt( Str, Size, cb, TRUE );
}
char* ConPromptNoHistory( char *Str, int Size, ConHookFunc cb )
{
return ConDoPrompt( Str, Size, cb, FALSE );
}
static char* ConDoPrompt( char *Str, int Size, ConHookFunc cb, Boolean UseHistory )
{
int i=0, j;
Str[i] = (char)getch( );
while ( Str[i]!='\r' && Str[i]!='\n' )
{
if ( cb != NULL )
{
if ( (*cb)(Str[i]) == 0 )
{
Str[i] = (char)getch( );
continue; // Don't process character.
}
}
switch ( Str[i] )
{
case ESC: // ESC (clear command-line)
while ( i > 0 )
{
putch( ' ' );
putch( 8 );
putch( 8 );
i--;
}
putch( ' ' );
putch( 8 );
break;
case 0x12: // CTRL-R (repeat last command)
if ( UseHistory )
{
j = 0;
while ( ConPromptStringSaved[j] != '\0' )
{
if ( i < Size-1 )
{
putch( ConPromptStringSaved[j] );
Str[i] = ConPromptStringSaved[j];
i++;
}
j++;
}
Str[i] = '\0';
}
break;
case 8: // BACKSPACE (delete last character)
if ( i > 0 )
{
putch( 8 );
putch( ' ' );
putch( 8 );
i--;
}
break;
case 0x7F: // CTRL-BACKSPACE (delete last word)
while ( i>0 && Str[i]!=' ' )
{
putch( ' ' );
putch( 8 );
putch( 8 );
i--;
}
// Remove any additional spaces.
while ( i>0 && Str[i-1]==' ' )
{
putch( 8 );
i--;
}
putch( ' ' );
putch( 8 );
break;
default:
if ( i < Size-1 )
{
if ( Str[i]>=0x20 && Str[i]<=0x7e )
{
putch( Str[i] );
i++;
}
else
putch( '\a' ); // Ring bell.
}
break;
}
#ifdef _WIN32
fflush( stdout );
#endif
Str[i] = (char)getch( );
}
Str[i] = '\0';
putch( '\n' );
#ifdef _WIN32
fflush( stdout );
#endif
// If nothing was typed, don't save the line.
if ( i == 0 )
return NULL;
// Save away the line to permit the repeat command.
if ( UseHistory )
{
while ( i >= 0 )
{
ConPromptStringSaved[i] = Str[i];
i--;
}
}
return Str;
}
int ConArgvAlloc( argvtype *pargv )
//
// Creates and allocates a standard DOS-like argv structure.
//
{
int argi=0;
int RetVal = TRUE;
for ( argi=0; argi<argvtypesize; argi++ )
{
(*pargv)[argi] = (char *) malloc( argvitemsize );
if ((*pargv)[argi] != NULL)
(*pargv)[argi][0] = '\0';
else
RetVal = FALSE;
}
return RetVal;
}
int ConArgvParse( char* pCmdLine, int CmdLineLen, argvtype *pargv )
//
// Creates a standard DOS-like argv structure from the command-line passed in.
// **IMPORTANT** ConArgvAlloc() must be called first to alloc each argv term.
//
// PARAMETERS:
//
// pCmdLine [in] - The whole command-line, including the command.
// CmdLineLen [in] - Length of the command including arguments.
// pargv [in&out] - Actual terms.
// Return Value [out] - Number of terms.
//
{
int argc, argi, i;
for ( argi=0; argi<argvtypesize; argi++ )
(*pargv)[argi][0] = '\0';
if ( CmdLineLen == 0 )
return 0;
argc = 0;
argi = 0;
while ( pCmdLine[argi]==' ' || pCmdLine[argi]=='\t' )
argi++; // Eat preceding whitespace.
for ( i=0; argi<=CmdLineLen && argc<argvtypesize; argi++ )
{
if ( pCmdLine[argi] == '\"' )
{
// Keep text enclosed in double-quotes as one argument.
do
{
if ( pCmdLine[argi]=='\\' && (argi+1)<CmdLineLen && (i+1)<argvitemsize-2 )
(*pargv)[argc][i++] = pCmdLine[argi++];
(*pargv)[argc][i++] = pCmdLine[argi++];
}
while ( argi<CmdLineLen && i<argvitemsize-2 && pCmdLine[argi]!='\"' );
(*pargv)[argc][i++] = pCmdLine[argi++];
}
if ( pCmdLine[argi]=='(' || pCmdLine[argi]=='[' )
{
// Keep text enclosed in brackets as one argument.
char StartChar = pCmdLine[argi];
char EndChar = (char)( StartChar=='(' ? ')' : ']' );
int nDeep = 0;
do
{
if ( pCmdLine[argi] == StartChar )
nDeep++;
if ( pCmdLine[argi] == EndChar )
nDeep--;
(*pargv)[argc][i++] = pCmdLine[argi++];
}
while ( argi<CmdLineLen && i<argvitemsize-2 && !(nDeep<=0 && pCmdLine[argi-1]==EndChar) );
}
if ( argi>=CmdLineLen || pCmdLine[argi]==' ' || pCmdLine[argi]=='\t' || pCmdLine[argi]=='\r' || pCmdLine[argi]=='\n' )
{
// Hit end of term.
(*pargv)[argc++][min(i,argvitemsize-1)] = '\0';
i = 0;
while ( (argi+1)<CmdLineLen && (pCmdLine[argi+1]==' ' || pCmdLine[argi+1]=='\t' || pCmdLine[argi+1]=='\r' || pCmdLine[argi+1]=='\n') )
argi++;
if ( (argi+1) == CmdLineLen )
argi = CmdLineLen + 1;
}
else
{
if ( i < argvitemsize-1 )
(*pargv)[argc][i++] = pCmdLine[argi];
}
}
return argc;
}
void ConArgvFree( argvtype *pargv )
//
// Frees any memory that was allocated for argv.
//
{
int argi;
for ( argi=0; argi<argvtypesize; argi++ )
{
if ( (*pargv)[argi] != NULL )
free( (*pargv)[argi] );
(*pargv)[argi] = NULL;
}
}
void ConSetBaseAddr( UInt32 BaseAddr )
{
ConBaseAddr = BaseAddr;
}
UInt32 ConGetBaseAddr( void )
{
return ConBaseAddr;
}
void ConSetAlternateMemAccess( ConReadFunc cbRead, ConWriteFunc cbWrite )
{
ConReadMem = cbRead;
ConWriteMem = cbWrite;
}
void ConSetScriptInterface( ConScriptFunc cbScript )
{
ConScript = cbScript;
}
Boolean ConDumpCommand( int Halt, int argc, argvtype argv )
//
// Show a memory dump.
//
// PARAMETERS:
//
// Halt [in] - The number of lines to show at a time. If 0, then
// halt is disabled.
// argc,argv [in] - The whole command-line (if you don't have an argv,
// call ConArgvAlloc() and ConArgvParse() first).
//
{
Int32 i;
UInt32 StartAddrAligned;
UInt8 LineCache[argvtypesize]; // Caches the memory access so that only one actual access occurs per memory location.
int iLine=1;
argc = 0; // Must reference un-used parameters to avoid stupid compiler warnings.
if ( argv[1][0] == '?' )
{
int argn = ConParseCommandLen( argv[0] );
printf( "\n" );
printf( " %*.*s [StartAddr [EndAddr|Len]]\n", argn, argn, argv[0] );
printf( " %*.*s8 [StartAddr [EndAddr|Len]]\n", argn, argn, argv[0] );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -