AppleWin/source/Debugger_Console.cpp

475 lines
12 KiB
C++
Raw Normal View History

2006-02-26 06:26:56 +00:00
/*
AppleWin : An Apple //e emulator for Windows
Copyright (C) 1994-1996, Michael O'Brien
Copyright (C) 1999-2001, Oliver Schmidt
Copyright (C) 2002-2005, Tom Charlesworth
Copyright (C) 2006, Tom Charlesworth, Michael Pohoreski
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AppleWin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Description: Debugger
*
* Author: Copyright (C) 2006, Michael Pohoreski
*/
#include "StdAfx.h"
#pragma hdrstop
#include <assert.h>
2006-02-26 06:26:56 +00:00
// Console ________________________________________________________________________________________
// See ConsoleInputReset() for why the console input
// is tied to the zero'th output of g_aConsoleDisplay
// and not using a seperate var: g_aConsoleInput[ CONSOLE_WIDTH ];
//
// : g_aConsoleBuffer[4] | ^ g_aConsoleDisplay[5] :
// : g_aConsoleBuffer[3] | | g_aConsoleDisplay[4] <- g_nConsoleDisplayTotal
// g_nConsoleBuffer -> g_aConsoleBuffer[2] | | g_aConsoleDisplay[3] :
// : g_aConsoleBuffer[1] v | g_aConsoleDisplay[2] :
// . g_aConsoleBuffer[0] -----> | g_aConsoleDisplay[1] .
// |
// g_aBufferedInput[0] -----> ConsoleInput ----> | g_aConsoleDisplay[0]
// g_aBufferedInput[1] ^
// g_aBufferedInput[2] |
// g_aBufferedInput[3] |
// Buffer
bool g_bConsoleBufferPaused = false; // buffered output is waiting for user to continue
int g_nConsoleBuffer = 0;
conchar_t g_aConsoleBuffer[ CONSOLE_BUFFER_HEIGHT ][ CONSOLE_WIDTH ]; // TODO: stl::vector< line_t >
2006-02-26 06:26:56 +00:00
// Cursor
char g_sConsoleCursor[] = "_";
2006-02-26 06:26:56 +00:00
// Display
char g_aConsolePrompt[] = ">!"; // input, assembler // NUM_PROMPTS
char g_sConsolePrompt[] = ">"; // No, NOT Integer Basic! The nostalgic '*' "Monitor" doesn't look as good, IMHO. :-(
int g_nConsolePromptLen = 1;
bool g_bConsoleFullWidth = true; // false
2006-02-26 06:26:56 +00:00
int g_iConsoleDisplayStart = 0; // to allow scrolling
int g_nConsoleDisplayTotal = 0; // number of lines added to console
int g_nConsoleDisplayLines = 0;
int g_nConsoleDisplayWidth = 0;
conchar_t g_aConsoleDisplay[ CONSOLE_HEIGHT ][ CONSOLE_WIDTH ];
2006-02-26 06:26:56 +00:00
// Input History
int g_nHistoryLinesStart = 0;
int g_nHistoryLinesTotal = 0; // number of commands entered
char g_aHistoryLines[ HISTORY_HEIGHT ][ HISTORY_WIDTH ] = {""};
2006-02-26 06:26:56 +00:00
// Input Line
2006-02-26 06:26:56 +00:00
// Raw input Line (has prompt)
conchar_t * const g_aConsoleInput = g_aConsoleDisplay[0];
2006-02-26 06:26:56 +00:00
// Cooked input line (no prompt)
int g_nConsoleInputChars = 0;
char * g_pConsoleInput = 0; // points to past prompt
const char * g_pConsoleFirstArg = 0; // points to first arg
bool g_bConsoleInputQuoted = false; // Allows lower-case to be entered
char g_nConsoleInputSkip = '~';
2006-02-26 06:26:56 +00:00
// Prototypes _______________________________________________________________
// Console ________________________________________________________________________________________
//===========================================================================
const conchar_t* ConsoleBufferPeek ()
2006-02-26 06:26:56 +00:00
{
return g_aConsoleBuffer[ 0 ];
}
//===========================================================================
bool ConsolePrint ( const char * pText )
{
while (g_nConsoleBuffer >= CONSOLE_BUFFER_HEIGHT)
{
ConsoleBufferToDisplay();
}
// Convert color string to native console color text
// Ignores g_nConsoleDisplayWidth
conchar_t c;
int x = 0;
const char * pSrc = pText;
conchar_t *pDst = & g_aConsoleBuffer[ g_nConsoleBuffer ][ 0 ];
while ((x < CONSOLE_WIDTH) && (c = *pSrc))
{
if ((c == '\n') || (x == (CONSOLE_WIDTH - 1)))
{
*pDst = 0;
x = 0;
if (g_nConsoleBuffer >= CONSOLE_BUFFER_HEIGHT)
{
ConsoleBufferToDisplay();
}
else
{
g_nConsoleBuffer++;
}
pSrc++;
pDst = & g_aConsoleBuffer[ g_nConsoleBuffer ][ 0 ];
}
else
if (ConsoleColor_IsCharMeta( c ))
{
pSrc++;
c = *pSrc;
if (c)
{
if (ConsoleColor_IsCharMeta( c ))
*pDst = c;
else
*pDst = ConsoleColor_Make( c );
x++;
pSrc++;
pDst++;
}
else
break;
}
else
{
*pDst = (c & _CONSOLE_COLOR_MASK);
x++;
pSrc++;
pDst++;
}
}
*pDst = 0;
g_nConsoleBuffer++;
return true;
}
2006-02-26 06:26:56 +00:00
// Add string to buffered output
// Shifts the buffered console output lines "Up"
//===========================================================================
bool ConsoleBufferPush ( const char * pText )
2006-02-26 06:26:56 +00:00
{
while (g_nConsoleBuffer >= CONSOLE_BUFFER_HEIGHT)
{
ConsoleBufferToDisplay();
}
conchar_t c;
int x = 0;
const char *pSrc = pText;
conchar_t *pDst = & g_aConsoleBuffer[ g_nConsoleBuffer ][ 0 ];
while ((x < CONSOLE_WIDTH) && (c = *pSrc))
{
if ((c == '\n') || (x == (CONSOLE_WIDTH - 1)))
2006-02-26 06:26:56 +00:00
{
*pDst = 0;
x = 0;
if (g_nConsoleBuffer >= CONSOLE_BUFFER_HEIGHT)
{
ConsoleBufferToDisplay();
}
else
{
g_nConsoleBuffer++;
}
pSrc++;
pDst = & g_aConsoleBuffer[ g_nConsoleBuffer ][ 0 ];
2006-02-26 06:26:56 +00:00
}
else
{
*pDst = (c & _CONSOLE_COLOR_MASK);
x++;
pSrc++;
pDst++;
2006-02-26 06:26:56 +00:00
}
}
*pDst = 0;
g_nConsoleBuffer++;
2006-02-26 06:26:56 +00:00
return true;
2006-02-26 06:26:56 +00:00
}
// Shifts the buffered console output "down"
//===========================================================================
void ConsoleBufferPop ()
2006-02-26 06:26:56 +00:00
{
int y = 0;
while (y < g_nConsoleBuffer)
{
strcpy( (char*)g_aConsoleBuffer[ y ], (char*)g_aConsoleBuffer[ y+1 ] );
2006-02-26 06:26:56 +00:00
y++;
}
g_nConsoleBuffer--;
if (g_nConsoleBuffer < 0)
g_nConsoleBuffer = 0;
}
// Remove string from buffered output
//===========================================================================
void ConsoleBufferToDisplay ()
2006-02-26 06:26:56 +00:00
{
ConsoleDisplayPush( (char*) ConsoleBufferPeek() );
2006-02-26 06:26:56 +00:00
ConsoleBufferPop();
}
//===========================================================================
Update_t ConsoleDisplayError ( const char * pText)
2006-02-26 06:26:56 +00:00
{
ConsoleBufferPush( pText );
return ConsoleUpdate();
}
// Shifts the console display lines "up"
//===========================================================================
void ConsoleDisplayPush ( const char * pText )
2006-02-26 06:26:56 +00:00
{
int nLen = MIN( g_nConsoleDisplayTotal, CONSOLE_HEIGHT - 1 - CONSOLE_FIRST_LINE);
while (nLen--)
{
strcpy(
(char*) g_aConsoleDisplay[(nLen + 1 + CONSOLE_FIRST_LINE )]
,(char*) g_aConsoleDisplay[nLen + CONSOLE_FIRST_LINE]
);
// , CONSOLE_WIDTH );
2006-02-26 06:26:56 +00:00
}
if (pText)
strcpy(
(char*) g_aConsoleDisplay[ CONSOLE_FIRST_LINE ]
, pText
);
// , CONSOLE_WIDTH );
2006-02-26 06:26:56 +00:00
g_nConsoleDisplayTotal++;
if (g_nConsoleDisplayTotal > (CONSOLE_HEIGHT - CONSOLE_FIRST_LINE))
g_nConsoleDisplayTotal = (CONSOLE_HEIGHT - CONSOLE_FIRST_LINE);
}
//===========================================================================
void ConsoleDisplayPause ()
2006-02-26 06:26:56 +00:00
{
if (g_nConsoleBuffer)
{
strcpy(
(char*) g_aConsoleInput,
"...press SPACE continue, ESC skip..."
);
g_nConsolePromptLen = strlen( g_pConsoleInput ) + 1;
g_nConsoleInputChars = 0;
2006-02-26 06:26:56 +00:00
g_bConsoleBufferPaused = true;
}
else
{
ConsoleInputReset();
}
}
//===========================================================================
bool ConsoleInputBackSpace ()
2006-02-26 06:26:56 +00:00
{
if (g_nConsoleInputChars)
{
g_pConsoleInput[ g_nConsoleInputChars ] = CHAR_SPACE;
2006-02-26 06:26:56 +00:00
g_nConsoleInputChars--;
if ((g_pConsoleInput[ g_nConsoleInputChars ] == CHAR_QUOTE_DOUBLE) ||
(g_pConsoleInput[ g_nConsoleInputChars ] == CHAR_QUOTE_SINGLE))
2006-02-26 06:26:56 +00:00
g_bConsoleInputQuoted = ! g_bConsoleInputQuoted;
g_pConsoleInput[ g_nConsoleInputChars ] = CHAR_SPACE;
2006-02-26 06:26:56 +00:00
return true;
}
return false;
}
// Clears prompt too
2006-02-26 06:26:56 +00:00
//===========================================================================
bool ConsoleInputClear ()
2006-02-26 06:26:56 +00:00
{
ZeroMemory( g_aConsoleInput, CONSOLE_WIDTH );
// Note: Alternate console, with no NULL end of line terminator
// for( int x = 0; x < CONSOLE_WIDTH; x++ )
// g_aConsoleInput[ x ] = CHAR_SPACE;
2006-02-26 06:26:56 +00:00
if (g_nConsoleInputChars)
{
// ZeroMemory( g_pConsoleInput, g_nConsoleDisplayWidth );
2006-02-26 06:26:56 +00:00
g_nConsoleInputChars = 0;
return true;
}
return false;
}
//===========================================================================
bool ConsoleInputChar ( const char ch )
2006-02-26 06:26:56 +00:00
{
if (g_nConsoleInputChars < g_nConsoleDisplayWidth) // bug? include prompt?
{
g_pConsoleInput[ g_nConsoleInputChars ] = ch;
g_nConsoleInputChars++;
return true;
}
return false;
}
//===========================================================================
void ConsoleUpdateCursor ( char ch )
{
if (ch)
g_sConsoleCursor[0] = ch;
else
{
ch = g_aConsoleInput[ g_nConsoleInputChars + g_nConsolePromptLen ];
if (! ch)
{
ch = CHAR_SPACE;
}
g_sConsoleCursor[0] = ch;
}
}
2006-02-26 06:26:56 +00:00
//===========================================================================
const char * ConsoleInputPeek ()
2006-02-26 06:26:56 +00:00
{
return (char*) g_aConsoleDisplay[0];
2006-02-26 06:26:56 +00:00
}
//===========================================================================
void ConsoleInputReset ()
{
// Not using g_aConsoleInput since we get drawing of the input Line for "Free"
// Even if we add console scrolling, we don't need any special logic to draw the input line.
g_bConsoleInputQuoted = false;
ConsoleInputClear();
// _tcscpy( g_aConsoleInput, g_sConsolePrompt ); // Assembler can change prompt
g_aConsoleInput[0] = g_sConsolePrompt[0];
g_nConsolePromptLen = 1;
// _tcscat( g_aConsoleInput, TEXT(" " ) );
2006-02-26 06:26:56 +00:00
int nLen = strlen( (char*) g_aConsoleInput );
g_pConsoleInput = (char*) &g_aConsoleInput[ g_nConsolePromptLen ]; // nLen];
2006-02-26 06:26:56 +00:00
g_nConsoleInputChars = 0;
}
//===========================================================================
int ConsoleInputTabCompletion ()
{
return UPDATE_CONSOLE_INPUT;
}
//===========================================================================
Update_t ConsoleScrollHome ()
{
g_iConsoleDisplayStart = g_nConsoleDisplayTotal - CONSOLE_FIRST_LINE;
if (g_iConsoleDisplayStart < 0)
g_iConsoleDisplayStart = 0;
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
Update_t ConsoleScrollEnd ()
{
g_iConsoleDisplayStart = 0;
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
Update_t ConsoleScrollUp ( int nLines )
{
g_iConsoleDisplayStart += nLines;
if (g_iConsoleDisplayStart > (g_nConsoleDisplayTotal - CONSOLE_FIRST_LINE))
g_iConsoleDisplayStart = (g_nConsoleDisplayTotal - CONSOLE_FIRST_LINE);
if (g_iConsoleDisplayStart < 0)
g_iConsoleDisplayStart = 0;
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
Update_t ConsoleScrollDn ( int nLines )
{
g_iConsoleDisplayStart -= nLines;
if (g_iConsoleDisplayStart < 0)
g_iConsoleDisplayStart = 0;
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
Update_t ConsoleScrollPageUp ()
{
ConsoleScrollUp( g_nConsoleDisplayLines - CONSOLE_FIRST_LINE );
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
Update_t ConsoleScrollPageDn ()
2006-02-26 06:26:56 +00:00
{
ConsoleScrollDn( g_nConsoleDisplayLines - CONSOLE_FIRST_LINE );
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
Update_t ConsoleBufferTryUnpause (int nLines)
2006-02-26 06:26:56 +00:00
{
for( int y = 0; y < nLines; y++ )
{
ConsoleBufferToDisplay();
}
g_bConsoleBufferPaused = false;
if (g_nConsoleBuffer)
{
g_bConsoleBufferPaused = true;
ConsoleDisplayPause();
return UPDATE_CONSOLE_INPUT | UPDATE_CONSOLE_DISPLAY;
2006-02-26 06:26:56 +00:00
}
return UPDATE_CONSOLE_DISPLAY;
2006-02-26 06:26:56 +00:00
}
//===========================================================================
Update_t ConsoleUpdate ()
2006-02-26 06:26:56 +00:00
{
if (! g_bConsoleBufferPaused)
{
int nLines = MIN( g_nConsoleBuffer, g_nConsoleDisplayLines - 1);
return ConsoleBufferTryUnpause( nLines );
2006-02-26 06:26:56 +00:00
}
return UPDATE_CONSOLE_DISPLAY;
}