home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ST-Computer Leser 2002 January
/
STC_CD_01_2002.iso
/
JAGUAR
/
JAG_SRC
/
SOURCE
/
DISARISC.C
< prev
next >
Wrap
C/C++ Source or Header
|
2001-08-11
|
12KB
|
443 lines
////////////////////////////////////////////////////////////////////////////////
// Jagulator: Atari Jaguar Console Emulation Project (disarisc.c)
// -----------------------------------------------------------------------------
// Jagulator is the Copyright (c) RealityMan 1998-2001 and is provided "as is"
// without any expressed or implied warranty. I have no Trademarks, Legal or
// otherwise. Atari, Jaguar and the Atari Logo are copyright Hasbro Inc. All
// other Copyrights and Trademarks are acknowledged. This project is in no way
// linked to Atari/Hasbro or other associated Atari companies.
//
// 07-07-2001 GH: New Source, Rewritten for Release 1.5.0
// 00-00-0000 GH: All Previous Source Considered as Development Code Only
#include "core.h"
////////////////////////////////////////////////////////////////////////////////
// Globals
char gpu_instr[][64] = {
"add ", "addc ", "addq ", "addqt ",
"sub ", "subc ", "subq ", "subqt ",
"neg ", "and ", "or ", "xor ",
"not ", "btst ", "bset ", "bclr ",
"mult ", "imult ", "imultn ", "resmac ",
"imacn ", "div ", "abs ", "sh ",
"shlq ", "shrq ", "sha ", "sharq ",
"ror ", "rorq ", "cmp ", "cmpq ",
"sat8 ", "sat16 ", "move ", "moveq ",
"moveta ", "movefa ", "movei ", "loadb ",
"loadw ", "load ", "loadp ", "load ",
"load ", "storeb ", "storew ", "store ",
"storep ", "store ", "store ", "move ",
"jump ", "jr ", "mmult ", "mtoi ",
"normi ", "nop ", "load ", "load ",
"store ", "store ", "sat24 ", ""
};
char dsp_instr[][64] = {
"add ", "addc ", "addq ", "addqt ",
"sub ", "subc ", "subq ", "subqt ",
"neg ", "and ", "or ", "xor ",
"not ", "btst ", "bset ", "bclr ",
"mult ", "imult ", "imultn ", "resmac ",
"imacn ", "div ", "abs ", "sh ",
"shlq ", "shrq ", "sha ", "sharq ",
"ror ", "rorq ", "cmp ", "cmpq ",
"subqmod ", "sat16s ", "move ", "moveq ",
"moveta ", "movefa ", "movei ", "loadb ",
"loadw ", "load ", "sat32s ", "load ",
"load ", "storeb ", "storew ", "store ",
"mirror ", "store ", "store ", "move ",
"jump ", "jr ", "mmult ", "mtoi ",
"normi ", "nop ", "load ", "load ",
"store ", "store ", "illegal ", "addqmod "
};
dword debuggpc; // Debug GPU Program Counter
dword debugdpc; // Debug DSP Program Counter
////////////////////////////////////////////////////////////////////////////////
//
char *decode_flags(int flags) /* Return a text string for the flags
field in a conditional instruction */
{
static char flastr[8+1]; /* Must be static so exists after return */
*flastr='\0'; /* Clear the result string */
if (flags==0x05) return("HI"); /* Special case for Carry clear and Zero clear */
if (flags&(1<<0)) strcat(flastr,"NE"); /* Zero clear */
if (flags&(1<<1)) strcat(flastr,"EQ"); /* Zero set */
if (flags&(1<<4)) { /* If set then bits 2,3 are for -ve flag */
if (flags&(1<<2)) strcat(flastr,"PL"); /* Sign clear */
if (flags&(1<<3)) strcat(flastr,"MI"); /* Sign set */
} else {
if (flags&(1<<2)) strcat(flastr,"CC"); /* Carry clear */
if (flags&(1<<3)) strcat(flastr,"CS"); /* Carry set */
}
return(flastr);
}
////////////////////////////////////////////////////////////////////////////////
// Disassemble DSP Code
void dspdebug_disassemble( int n )
{
#ifdef DEBUG
dword iw, src, dst, ir;
long msw, lsw;
long movei_long;
while( n-- )
{
iw = mem_readword( debugdpc );
print( "%06X: %04X", debugdpc, iw );
debugdpc += 2;
src = (iw & 0x03E0) >> 5; // Get Source
dst = (iw & 0x001F); // Get Destination
print( "%s", dsp_instr[iw >> 10] );
switch( iw >> 10 )
{
// 0 Parameter Instructions
case NOP:
break;
// 1 Register Parameter Instructions
case NEG:
case NOT:
case RESMAC:
case ABS:
case SAT16S:
case SAT32S:
case MIRROR:
print( "r%02d", dst ); // Just the Destination
break;
case MOVE_PC:
print( "pc,r%02d", dst );
break;
// 2 Register Parameter Instructions
case ADD:
case ADDC:
case SUB:
case SUBC:
case AND:
case OR:
case XOR:
case MULT:
case IMULT:
case IMULTN:
case IMACN:
case DIV:
case SH:
case SHA:
case ROR:
case CMP:
case MOVE:
case MOVETA:
case MOVEFA:
case MMULT:
case MTOI:
case NORMI:
print( "r%02d,r%02d", src, dst );
break;
// Quick Immediate Instrctions with 1 Register Parameter
case ADDQ:
case ADDQT:
case SUBQ:
case SUBQT:
case SHRQ:
case SHARQ:
case RORQ:
case ADDQMOD:
case SUBQMOD:
if( !src ) src = 32;
print( "#%02d,r%02d", src, dst );
break;
case SHLQ:
print( "#%02d,r%02d", 32 - src, dst );
break;
case BTST:
case BSET:
case BCLR:
case MOVEQ:
print( "#%02d,r%02d", src, dst );
break;
case CMPQ:
if( src >= 16 ) src -= 32;
print( "#%02d,r%02d", src, dst );
break;
// Non-Offsetted LOAD
case LOADB:
case LOADW:
case LOAD:
print( "(r%02d),r%02d", src, dst );
break;
// Non-Offsetted STORE
case STOREB:
case STOREW:
case STORE:
print( "r%02d,(r%02d)", dst, src );
break;
// Immediate Offset LOAD
case LOAD_14I:
case LOAD_15I:
ir = ( iw = LOAD_14I ? 14 : 15);
if( !src ) src = 32;
print( "(r%02d + #%02d),r%02d", ir, src * 4, dst );
break;
// Immediate Offset STORE
case STORE_14I:
case STORE_15I:
ir = ( iw = STORE_14I ? 14 : 15 );
if( !src ) src = 32;
print( "r%02d,(r%02d + #%02d)", dst, ir, src * 4 );
break;
// Register Offset LOAD
case LOAD_14R:
case LOAD_15R:
ir = ( iw = LOAD_14R ? 14 : 15 );
print( "(r%02d + r%02d),r%02d", ir, src, dst );
break;
// Register Offset STORE
case STORE_14R:
case STORE_15R:
ir = ( iw = STORE_14R ? 14 : 15 );
print( "r%02d,(r%02d + r%02d)", dst, ir, src );
break;
// MOVEI Instruction
case MOVEI:
lsw = mem_readword( debuggpc );
debugdpc += 2;
msw = mem_readword( debuggpc );
debugdpc += 2;
if( lsw < 0 || msw < 0 )
{
print( YEL"Insufficient Source Data!!!\n" );
}
else
{
movei_long = msw << 16 | lsw;
print( "0x%08x,r%02d", movei_long, dst );
}
break;
// JUMP Instruction
case JUMP:
if( dst ) print ( "%s,", decode_flags( dst ) );
print( "(r%02d)", src );
break;
// JR Instruction
case JR:
if( dst ) print( "%s,", decode_flags( dst ) );
if( src >= 16 ) src -= 32;
printf("$%lx",debuggpc+src*2);
break;
default:
print( YEL"Illegal DSP Opcode!!!\n" );
break;
}
print( "\n" );
}
#endif
}
////////////////////////////////////////////////////////////////////////////////
// Disassemble GPU Code
void gpudebug_disassemble( int n )
{
#ifdef DEBUG
dword iw, src, dst, ir;
long msw, lsw;
long movei_long;
while( n-- )
{
iw = mem_readword( debuggpc );
print( "%06X: ", debuggpc );
debuggpc += 2;
src = (iw & 0x03E0) >> 5; // Get Source
dst = (iw & 0x001F); // Get Destination
print( "%s", gpu_instr[iw >> 10] );
switch( iw >> 10 )
{
// 0 Parameter Instructions
case NOP:
break;
// 1 Register Parameter Instructions
case PACK_UNPACK:
if( src ) // Source is 1 for UNPACK
print( "unpack " );
else
print( "pack " );
case NEG:
case NOT:
case RESMAC:
case ABS:
case SAT8:
case SAT16:
case SAT24:
print( "r%02d", dst ); // Just the Destination
break;
case MOVE_PC:
print( "pc,r%02d", dst );
break;
// 2 Register Parameter Instructions
case ADD:
case ADDC:
case SUB:
case SUBC:
case AND:
case OR:
case XOR:
case MULT:
case IMULT:
case IMULTN:
case IMACN:
case DIV:
case SH:
case SHA:
case ROR:
case CMP:
case MOVE:
case MOVETA:
case MOVEFA:
case MMULT:
case MTOI:
case NORMI:
print( "r%02d,r%02d", src, dst );
break;
// Quick Immediate Instrctions with 1 Register Parameter
case ADDQ:
case ADDQT:
case SUBQ:
case SUBQT:
case SHRQ:
case SHARQ:
case RORQ:
if( !src ) src = 32;
print( "#%02d,r%02d", src, dst );
break;
case SHLQ:
print( "#%02d,r%02d", 32 - src, dst );
break;
case BTST:
case BSET:
case BCLR:
case MOVEQ:
print( "#%02d,r%02d", src, dst );
break;
case CMPQ:
if( src >= 16 ) src -= 32;
print( "#%02d,r%02d", src, dst );
break;
// Non-Offsetted LOAD
case LOADB:
case LOADW:
case LOAD:
case LOADP:
print( "(r%02d),r%02d", src, dst );
break;
// Non-Offsetted STORE
case STOREB:
case STOREW:
case STORE:
case STOREP:
print( "r%02d,(r%02d)", dst, src );
break;
// Immediate Offset LOAD
case LOAD_14I:
case LOAD_15I:
ir = ( iw = LOAD_14I ? 14 : 15);
if( !src ) src = 32;
print( "(r%02d + #%02d),r%02d", ir, src * 4, dst );
break;
// Immediate Offset STORE
case STORE_14I:
case STORE_15I:
ir = ( iw = STORE_14I ? 14 : 15 );
if( !src ) src = 32;
print( "r%02d,(r%02d + #%02d)", dst, ir, src * 4 );
break;
// Register Offset LOAD
case LOAD_14R:
case LOAD_15R:
ir = ( iw = LOAD_14R ? 14 : 15 );
print( "(r%02d + r%02d),r%02d", ir, src, dst );
break;
// Register Offset STORE
case STORE_14R:
case STORE_15R:
ir = ( iw = STORE_14R ? 14 : 15 );
print( "r%02d,(r%02d + r%02d)", dst, ir, src );
break;
// MOVEI Instruction
case MOVEI:
lsw = mem_readword( debuggpc );
debuggpc += 2;
msw = mem_readword( debuggpc );
debuggpc += 2;
if( lsw < 0 || msw < 0 )
{
print( "Insufficient Source Data\n" );
}
else
{
movei_long = msw << 16 | lsw;
print( "0x%08x,r%02d", movei_long, dst );
}
break;
// JUMP Instruction
case JUMP:
if( dst ) print ( "%s,", decode_flags( dst ) );
print( "(r%02d)", src );
break;
// JR Instruction
case JR:
if( dst ) print( "%s,", decode_flags( dst ) );
if( src >= 16 ) src -= 32;
printf("$%lx",debuggpc+src*2);
break;
default:
print( "**** UNUSED OPCODE %d ****", iw );
break;
}
print( "\n" );
}
#endif
}