📄 play.c
字号:
}
/*-- Conversion Functions -----------------------------------------------*/
/*
** IntToBin - INTeger TO BINary ASCII conversion.
**
** Returns a binary string representing the passed in
** integer (eg. '5' becomes '00000101')
**
** The string pointed to by szStr must be long enough to hold the
** converted value.
*/
void IntToBin( int nVal, int nWidth, PCHAR szStr )
{
nWidth--;
while (nWidth >= 0)
{
if (nVal & (1 << nWidth))
*szStr = '1';
else
*szStr = '0';
szStr++;
nWidth--;
}
*szStr = '\0';
}
/*-------------------------------------------------------------------------*/
/*
** AscToUpper()
**
** This function converts an ASCII string to upper case.
*/
void AscToUpper(PCHAR szAscii)
{
while (*szAscii != 0)
{
if ((*szAscii <= 'z') && (*szAscii >= 'a'))
*szAscii -= 'a' - 'A';
++szAscii;
}
}
/*-------------------------------------------------------------------------*/
/*
** AscToLong()
**
** This function converts an ASCII string to a long integer.
** This function works the same as atol() with the exception that the
** input string is scanned for radix modifiers and handled appropriately.
**
** If not specified the input value is assumed to be HEX.
** Octal values are not handled.
**
** Returns:
** 0 if the calls fails (A very broken interface but it follows atol())
*/
long AscToLong(PCHAR szASCII)
{
PCHAR ptr;
ptr = szASCII;
/*
** Scan for a radix modifier.
*/
while (!isspace((int)(*ptr)) && ('\0' != *ptr))
ptr++;
/*
** Handle the appropriate base.
*/
switch (toupper(*(ptr - 1)))
{
case 'T':
return atol(szASCII);
break;
case 'B':
if (DELIM == *(ptr - 2))
return btol(szASCII);
else
return htol(szASCII);
break;
case 'H':
default:
return htol(szASCII);
break;
}
}
/*-------------------------------------------------------------------------*/
/*
** btol() - Binary ASCII TO Long integer.
*/
long btol(PCHAR szASCII)
{
long lTmp = 0;
char ch;
SKIP_WHITESPACE( szASCII );
/*
** Check that we have no more than 32 'bits' of argument.
*/
if (ArgLen(szASCII) > 32)
return 0;
while (DELIM != *szASCII)
{
ch = *szASCII;
if ((ch != '0') && (ch != '1'))
return 0;
lTmp = (lTmp << 1) + (ch - '0');
szASCII++;
}
return lTmp;
}
/*-------------------------------------------------------------------------*/
/*
** htol() - Hexadecimal ASCII to Long integer.
*/
long htol(PCHAR szASCII)
{
long lTmp;
char ch;
lTmp = 0;
SKIP_WHITESPACE( szASCII );
/*
** Check that we have no more than 32 'bits' of argument.
*/
if (ArgLen( szASCII ) > 32/4)
return 0;
while (!isspace((int)(*szASCII)) && ('\0' != *szASCII))
{
ch = (char)toupper( *szASCII );
if (!isxdigit( (int)ch ))
return 0;
if ((ch >= 'A') && (ch <= 'F'))
lTmp = lTmp * 16 + 10 + (ch - 'A');
else
lTmp = lTmp * 16 + (ch - '0');
szASCII++;
}
return lTmp;
}
/*-------------------------------------------------------------------------*/
/*
** ArgLen()
**
** Returns:
** The length of the argument pointed to by szArg but
** does not include the final delimiter in the length.
*/
int ArgLen( PCHAR szArg )
{
int nLen = 0;
while (!isspace( (int)(*szArg) ) && ('\0' != *szArg))
{
szArg++;
nLen++;
}
return nLen;
}
/*-------------------------------------------------------------------------*/
/*
** FindNextArg()
**
** This function scans the input string to see if there is another argument,
** separated by a whitespace, in the string. If an argument is found szArg
** is updated to point to the start of non-whitespace forming the argument.
**
** Returns:
** TRUE - if another argument is found - szArg is updated.
** FALSE - if no other arguments found - szArg is not updated.
*/
BOOL FindNextArg(char ** szArg)
{
PCHAR ptr = *szArg;
/*
** Look for the first whitespace.
*/
while (!isspace((int)(*ptr)) && (*ptr != '\0'))
ptr++;
if (*ptr == '\0')
return FALSE;
/*
** Look for the first non-whitespace.
*/
while (isspace((int)(*ptr)) && (*ptr != '\0') && (*ptr != ';'))
ptr++;
/*
** If we came to an EOL or a comment then return FALSE.
*/
if (('\0' == *ptr) || (';' == *ptr))
return FALSE;
/*
** Return TRUE if we didn't hit an EOL.
*/
*szArg = ptr;
return TRUE;
}
/*-------------------------------------------------------------------------*/
/*
** DisplayAllRegisters()
**
** This function reads and displays the contents of all the 13706
** control registers. No interpretation is done.
*/
void DisplayAllRegisters( void )
{
unsigned val;
int count, count2;
int addr;
int LastAddr;
const WORD RegStartAddr[] =
{ 0x00, 0x10, 0x20, 0x70, 0x80, 0x90,
0xa0, 0xb0 };
LastAddr = RegStartAddr[0];
for (count = 0; count < sizeof(RegStartAddr) / sizeof(WORD); ++count)
{
addr = RegStartAddr[count];
HaltDisplay();
printf("\n");
printf("[%04X] ", addr);
for (count2 = 0; count2 < 16; ++count2, ++addr)
{
val = seReadRegByte(addr);
printf("%02X", val);
if (count2 == 7)
printf("-");
else
printf(" ");
}
LastAddr = addr;
}
printf("\n");
HaltDisplay();
printf("\nGCP Data Registers:");
HaltDisplay();
for (count = 0; count < 32; count++)
{
if (count%16 ==0 )
{
HaltDisplay();
printf("\n[%04x] ", count);
}
seWriteRegByte(0x28, count);
printf ("%02x ", seReadRegByte(0x2c));
}
}
/*==== Command Handlers ===================================================*/
/*
** Completes the parsing and executes the (L)UT command.
*/
void HandleLutIO( PCHAR szArg )
{
int nIdx;
BYTE byLut[3];
/*
** If the command was 'LA' then dump all the LUT entries.
*/
if ('A' == toupper(*(szArg + 1)))
{
for (nIdx = 0; nIdx < NUM_LUT; nIdx++ )
{
if (0 == (nIdx & 3))
{
if (TRUE == HaltDisplay())
break;
printf("\nL[%02X]", nIdx );
}
seReadLutEntry(nIdx, &byLut[0]);
printf(" %02X %02X %02X", byLut[0], byLut[1], byLut[2]);
}
return;
}
/*
** Otherwise ensure the command is all by itself.
*/
if (!isspace((int)(*(szArg + 1))))
{
DISPLAY_WHAT;
return;
}
/*
** We MUST have an index.
*/
if (FALSE == FindNextArg(&szArg))
{
DISPLAY_WHAT;
return;
}
nIdx = (WORD)AscToLong(szArg);
if (nIdx > NUM_LUT)
{
DISPLAY_WHAT;
return;
}
/*
** If we don't find any other arguments then do a read.
*/
if (FALSE == FindNextArg( &szArg ))
{
seReadLutEntry(nIdx, &byLut[0]);
printf("\n L[%02X] > %02X %02X %02X", nIdx, byLut[0], byLut[1], byLut[2]);
return;
}
/*
** We found another argument - RED - therefore, we MUST have 3 arguments.
*/
byLut[HAL_RED] = (BYTE)AscToLong(szArg);
if (FALSE == FindNextArg(&szArg))
{
printf("\a\nDid not find green LUT value");
return;
}
byLut[HAL_GREEN] = (BYTE)AscToLong(szArg);
if (FALSE == FindNextArg(&szArg))
{
printf("\a\nDid not find blue LUT value");
return;
}
byLut[HAL_BLUE] = (BYTE)AscToLong(szArg);
seWriteLutEntry(nIdx, &byLut[0]);
}
/*-------------------------------------------------------------------------*/
void HandleRegIO( PCHAR szArg )
{
DWORD dwIdx;
unsigned val;
DWORD dwVal;
char szBinary[50];
int RegSize = 1;
/*
** Are we to dump all the registers?
*/
if ('A' == toupper( *(szArg + 1) ))
{
DisplayAllRegisters();
return;
}
if ('D' == toupper ( *(szArg + 1) ))
RegSize = 4;
else if ('W' == toupper ( *(szArg + 1) ))
RegSize = 2;
else
RegSize = 1;
/*
** Otherwise ensure the command is all by itself.
*/
if ((RegSize == 1) && !isspace((int) *(szArg + 1)))
{
DISPLAY_WHAT;
return;
}
if (FALSE == FindNextArg( &szArg ))
{
DISPLAY_WHAT;
return;
}
dwIdx = AscToLong( szArg );
if (FALSE == FindNextArg( &szArg ))
{
switch (RegSize)
{
case 4:
// Read dword without swapping bytes if endian of system is big-endian.
dwVal = ReadRegDword(dwIdx);
IntToBin( dwVal, 32, szBinary );
printf( "\n [%lX] > %08lX %sb %lut",
dwIdx, dwVal, szBinary, dwVal );
break;
case 2:
// Read word without swapping bytes if endian of system is big-endian.
val = ReadRegWord(dwIdx);
IntToBin( (DWORD) val, 16, szBinary );
printf( "\n [%lX] > %04X %sb %3ut",
dwIdx, val, szBinary, val );
break;
default:
val = seReadRegByte(dwIdx);
IntToBin( (DWORD) val, 8, szBinary );
printf( "\n [%lX] > %02X %sb %3ut",
dwIdx, val, szBinary, val );
break;
}
return;
}
else
{
switch (RegSize)
{
case 4:
dwVal = AscToLong(szArg);
// Write dword without swapping bytes if endian of system is big-endian.
WriteRegDword(dwIdx, dwVal);
printf( "\n [%lX] < %08lX", dwIdx, dwVal );
break;
case 2:
val = (unsigned) AscToLong(szArg);
// Write word without swapping bytes if endian of system is big-endian.
WriteRegWord(dwIdx, val);
printf( "\n [%lX] < %04X", dwIdx, val );
break;
default:
val = (unsigned) AscToLong(szArg);
seWriteRegByte(dwIdx, val);
printf( "\n [%lX] < %02X", dwIdx, val );
break;
}
return;
}
}
/*-----------------------------------------------------------------------*/
void HandleFill( PCHAR szArg )
{
int MemSize = 1; /* 1 == bytes, 2 == words, 4 == dwords */
BOOL bOneArgPat;
DWORD dwOffset, dwEndOffset;
DWORD dwPattern;
int NoArguments;
char *szTmp;
bOneArgPat = FALSE;
szTmp = szArg;
if (FALSE == FindNextArg( &szTmp ))
NoArguments = TRUE;
else
NoArguments = FALSE;
/*
** Check if there is a WORD or DWORD modifier.
*/
if (szTmp == &szArg[2])
MemSize = 1;
else if (('W' == toupper(szArg[1])) && (NoArguments || (szTmp == &szArg[3])))
MemSize = 2;
else if (('D' == toupper(szArg[1])) && (NoArguments || (szTmp == &szArg[3])))
MemSize = 4;
else
{
DISPLAY_WHAT;
return;
}
/*
** We MUST have a starting offset.
*/
if (FALSE == FindNextArg( &szArg ))
{
DISPLAY_WHAT;
return;
}
dwOffset = AscToLong( szArg );
/*
** We MUST have an ending offset.
**
*** Should the ability to parse out a (L)ength be made here?
*/
if (FALSE == FindNextArg( &szArg ))
{
DISPLAY_WHAT;
return;
}
dwEndOffset = AscToLong( szArg );
/*
** For now we force the user to order the start and end addresses.
*/
if (dwOffset >= dwEndOffset)
{
DISPLAY_WHAT;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -