home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ST-Computer Leser 2002 January
/
STC_CD_01_2002.iso
/
JAGUAR
/
JAG_SRC
/
SOURCE
/
BOOT.C
< prev
next >
Wrap
C/C++ Source or Header
|
2001-08-18
|
23KB
|
682 lines
////////////////////////////////////////////////////////////////////////////////
// Jagulator: Atari Jaguar Console Emulation Project (boot.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
// Fetchable Code Areas
struct STARSCREAM_PROGRAMREGION memFetch[] = {
{ 0x000000, 0x3FFFFF, (unsigned)st.ram - 0x000000 },
{ 0x800000, 0xDFFFFF, (unsigned)st.game - 0x800000 },
{ 0xE00000, 0xE1FFFF, (unsigned)st.boot - 0xE00000 },
{ 0xF00000, 0xF0FFFF, (unsigned)st.tom - 0xF00000 },
{ 0xF10000, 0xF1FFFF, (unsigned)st.jerry - 0xF10000 },
{ -1, -1, (unsigned)NULL }
};
// Read Byte
struct STARSCREAM_DATAREGION memReadByte[] = {
{ 0x000000, 0x3FFFFF, NULL, st.ram },
{ 0x800000, 0xDFFFFF, NULL, st.game },
{ 0xE00000, 0xE1FFFF, NULL, st.boot },
{ 0xF00000, 0xF0FFFF, NULL, st.tom },
{ 0xF10000, 0xF1FFFF, NULL, st.jerry },
{ -1, -1, NULL, NULL }
};
// Read Word
struct STARSCREAM_DATAREGION memReadWord[] = {
{ 0x000000, 0x3FFFFF, NULL, st.ram },
{ 0x800000, 0xDFFFFF, NULL, st.game },
{ 0xE00000, 0xE1FFFF, NULL, st.boot },
{ 0xF00000, 0xF0FFFF, mem_tomreadw, st.tom },
{ 0xF10000, 0xF1FFFF, mem_jryreadw, st.jerry },
{ -1, -1, NULL, NULL }
};
// Write Byte
struct STARSCREAM_DATAREGION memWriteByte[] = {
{ 0x000000, 0x3FFFFF, NULL, st.ram },
{ 0xF00000, 0xF0FFFF, NULL, st.tom },
{ 0xF10000, 0xF1FFFF, NULL, st.jerry },
{ -1, -1, NULL, NULL }
};
// Write Word
struct STARSCREAM_DATAREGION memWriteWord[] = {
{ 0x000000, 0x3FFFFF, NULL, st.ram },
{ 0xF00000, 0xF0FFFF, mem_tomwritew, st.tom },
{ 0xF10000, 0xF1FFFF, mem_jrywritew, st.jerry },
{ -1, -1, NULL, NULL }
};
typedef struct {
dword crc; // CRC
dword title; // Description/Title
dword supp; // Supported Y/N
dword format; // 1 = BIN, 2 = JAG
dword offset; // Load Offset
dword loadaddr; // Load Address
dword hres; // Horizontal Resolution
dword vres; // Vertical Resolution
} ROMTABLE;
// Rom Titles
char *romt[] = {
// 0
"Asteroids by Sinister Developments\0",
"BadCode0 Demo by BadCoder\0",
"BadCode1 Demo by BadCoder\0",
"BadCode2 Demo by BadCoder\0",
"BadCode3 Demo by BadCoder\0",
// 5
"BadCode4 Demo by BadCoder\0",
"BadCode4c Demo by BadCoder\0",
"BadCode4 (Metal) Demo by BadCoder\0",
"Colors (CrY Color Picker) by Matthias Domin\0",
"Gorf by 3D Stooges Software\0",
// 10
"JagMania by Matthias Domin\0",
"JDC Demo V1 by Lars Hannig\0",
"JoyPad Tester by Matthias Domin\0",
"Legion Force Jidai Demo by Force Design\0",
// Extras
"Atari Jaguar Object Processor Tester V2 by Lars Hanning\0",
"\0"
};
ROMTABLE roms[] = {
0xDF188AF5, 9, 1, 1, 0x00000000, 0x00004000, 340, 299,
0xA6B07EFA, 8, 1, 1, 0x00000000, 0x00005000, 380, 286,
0x17B9C4DD, 8, 1, 2, 0x0000002E, 0x00005000, 380, 286,
0x3C6E7EFA, 10, 1, 1, 0x00000000, 0x00005000, 448, 338,
0xF046AD6B, 10, 1, 2, 0x0000002E, 0x00005000, 448, 338,
0x874650A4, 0, 1, 1, 0x00000000, 0x00020000, 404, 301,
0x5F141A2A, 13, 1, 1, 0x00000000, 0x00005000, 352, 286,
0x6B902FD1, 12, 1, 2, 0x0000002E, 0x00005000, 448, 295,
0xB4FB9F2E, 12, 1, 1, 0x00000000, 0x00005000, 448, 295,
0xF150D92B, 11, 1, 1, 0x00000000, 0x00004000, 380, 263,
0xD05AD7EE, 1, 1, 1, 0x00000000, 0x00004000, 380, 280,
0x6BD289A7, 2, 1, 1, 0x00000000, 0x00004000, 380, 280,
0x70E19B3F, 3, 1, 1, 0x00000000, 0x00004000, 380, 280,
0xAAF9123C, 4, 1, 1, 0x00000000, 0x00004000, 380, 280,
0xFFFFFFFF, 5, 1, 1, 0x00000000, 0x00004000, 380, 280,
0xFFFFFFFF, 6, 1, 1, 0x00000000, 0x00004000, 380, 280,
0xEBCED8F5, 7, 1, 1, 0x00000000, 0x00004000, 368, 292,
0x414F4CD1, 4, 1, 2, 0x0000002E, 0x00004000, 380, 280,
0xFFFFFFFF, 5, 1, 2, 0x0000002E, 0x00004000, 380, 280,
0x411D1B4F, 7, 1, 2, 0x0000002E, 0x00004000, 368, 292,
0x2930F2A3, 14, 1, 1, 0x00000000, 0x00004000, 362, 302,
0x00000000, 999, 0, 0, 0x00000000, 0x00000000, 0, 0
};
////////////////////////////////////////////////////////////////////////////////
// CRC Calculation Code
// Usage:
// unsigned long crc = -1L
// crc = crc32(buffer, length, crc)
static unsigned long *CRCTable; // Table constructed for fast lookup.
#define CRC32_POLYNOMIAL 0xEDB88320L
// Initialize the CRC calculation table
static int BuildCRCTable(void)
{
int i, j;
unsigned long crc;
CRCTable = malloc(256 * sizeof(unsigned long));
if (CRCTable == NULL)
{
fprintf(stderr, "Can't malloc space for CRC table in file %s\n", __FILE__);
return -1L;
}
for (i = 0; i <= 255; i++)
{
crc = i;
for (j = 8; j > 0; j--)
if (crc & 1)
crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
else
crc >>= 1;
CRCTable[i] = crc;
}
return 0;
}
unsigned long crc32(void *buffer, unsigned int count, unsigned long crc)
{
unsigned long temp1, temp2;
static int firsttime = 1;
unsigned char *p = (unsigned char *)buffer;
if (firsttime)
{
if (BuildCRCTable())
return -1;
firsttime = 0;
}
while (count-- != 0)
{
temp1 = (crc >> 8) & 0x00FFFFFFL;
temp2 = CRCTable[((int)crc ^ *p++) & 0xFF];
crc = temp1 ^ temp2;
}
return crc;
}
////////////////////////////////////////////////////////////////////////////////
// Start Core Jaguar Emulation Here (68000 Command Processor)
void boot_jaguar( dword address )
{
// Tie Memory Map into the CPU Context
s68000context.s_fetch = memFetch;
s68000context.u_fetch = memFetch;
s68000context.s_readbyte = memReadByte;
s68000context.u_readbyte = memReadByte;
s68000context.s_readword = memReadWord;
s68000context.u_readword = memReadWord;
s68000context.s_writebyte = memWriteByte;
s68000context.u_writebyte = memWriteByte;
s68000context.s_writeword = memWriteWord;
s68000context.u_writeword = memWriteWord;
// Initialise and Rest StarScream CPU
s68000init();
s68000reset();
// Initialisation
blt.bltInactive = TRUE; // Blitter is Inactive
gst.div16 = FALSE; // Disable 16.16 Division
#ifdef DEBUG
print( "%% Initialising System to NTSC\n" );
#endif
*(word *)(st.jerry + 0x4002) |= VIDTYPE;
s68000context.areg[7] = address; // Set Stack
s68000context.pc = address; // Set Program Counter
wsprintf( sbbuf, "Emulating..." );
SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
cpu_exec();
}
////////////////////////////////////////////////////////////////////////////////
// Entry Point for Rom Loading
dword boot_load( void )
{
dword gamesize; // Size of Loaded Game Rom
dword bootsize; // Size of Loaded Boot Rom
byte tmp; // Temporary Byte Storage
static char buf[MAX_PATH]; // Temporary Buffer
dword crc; // CRC Value of Rom
dword i, j; // Iterators
FILE *hFile; // Handle to File
OPENFILENAME OpenFileName; // Structure for Open Common Dialog
TCHAR fname[ MAX_PATH ] = "\0"; // Filename
LPCTSTR szFilterI = "Jaguar Rom Images (bin,jag,rom,abs)\0"
"*.bin;*.jag;*.rom;*.abs\0"
"All Files (*.*)\0"
"*.*\0\0";
DWORD ofnFlags = OFN_FILEMUSTEXIST |
OFN_HIDEREADONLY |
OFN_PATHMUSTEXIST;
OpenFileName.lpstrFilter = szFilterI;
OpenFileName.lpstrTitle = "Load Atari Jaguar Rom";
OpenFileName.lpstrDefExt = "*.bin";
OpenFileName.lStructSize = sizeof( OPENFILENAME );
OpenFileName.hwndOwner = hwndMain;
OpenFileName.hInstance = hInst;
OpenFileName.lpstrCustomFilter = (LPTSTR) NULL;
OpenFileName.nMaxCustFilter = 0;
OpenFileName.nFilterIndex = 1L;
OpenFileName.lpstrFile = fname;
OpenFileName.nMaxFile = sizeof( fname );
OpenFileName.lpstrFileTitle = NULL;
OpenFileName.nMaxFileTitle = 0;
OpenFileName.lpstrInitialDir = cfg.rompath;
OpenFileName.nFileOffset = 0;
OpenFileName.nFileExtension = 0;
OpenFileName.Flags = ofnFlags;
OpenFileName.lCustData = 0;
OpenFileName.lpfnHook = NULL;
OpenFileName.lpTemplateName = NULL;
if( GetOpenFileName( &OpenFileName ) )
{
v_deinit();
memset( &st, 0, sizeof( STATE ) );
memset( &gst, 0, sizeof( GPUSTATE ) );
memset( &dst, 0, sizeof( DSPSTATE ) );
memset( &blt, 0, sizeof( BLTSTATE ) );
wsprintf( sbbuf, "%s", COPYRIGHT );
SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
// File Selected
hFile = fopen( fname, "rb" );
if( hFile == NULL )
{
wsprintf( sbbuf, "Could not open \'%s\'...", fname );
SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
error( "Could not open \'%s\'", fname );
st.readytogo = 0;
flushdisplay();
return( FALSE );
}
fseek( hFile, 0L, SEEK_SET );
fread( buf, 1, MAX_PATH, hFile );
fclose( hFile );
// Check if Rom is Supported
crc = crc32( buf, MAX_PATH, -1 );
for( i = 0; ; i++ )
{
if( roms[i].crc == crc ) break;
if( !roms[i].crc ) // Unsupported Jaguar Rom
{
wsprintf( sbbuf, "ERROR: Rom is either not supported or not a valid Atari Jaguar rom image..." );
SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
print( YEL"Error: This rom is not supported by Jagulator "
"or is not a recognised\n"
YEL" Atari Jaguar rom image.\n" );
flushdisplay();
st.readytogo = 0;
return( FALSE );
}
}
// Load Boot Rom
strcpy( buf, cfg.bootpath );
strcat( buf, "jagboot.rom" );
print( "%% Loading Boot Rom Image \'%s\'\n", buf );
wsprintf( sbbuf, "Loading Boot Rom Image \'%s\'...", buf );
SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
flushdisplay();
hFile = fopen( buf, "rb" );
if( hFile == NULL )
{
wsprintf( sbbuf, "Could Not Load Boot Rom...." );
SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
error( "Could Not Open Boot Rom." );
print( "This file must be named 'jagboot.rom' and be located"
" in the 'Boot Path'\n" );
st.readytogo = 0;
flushdisplay();
return( FALSE );
}
else
{
fseek( hFile, 0L, SEEK_END );
bootsize = ftell( hFile );
if( bootsize != 131072 )
{
fclose( hFile );
wsprintf( sbbuf, "Invalid Boot Rom File Size..." );
SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
error( "Invalid Boot Rom File Size." );
st.readytogo = 0;
flushdisplay();
return( FALSE );
}
fseek( hFile, 0L, SEEK_SET );
fread( st.boot, 1, bootsize, hFile );
fclose( hFile );
}
// Byte Swap Boot Rom
for( j = 0; j < bootsize; j+=2 )
{
tmp = st.boot[j];
st.boot[j] = st.boot[j+1];
st.boot[j+1] = tmp;
}
// Load Game Rom
wsprintf( sbbuf, "Loading Rom Image from '%s' to 0x%06X\n", fname, roms[i].loadaddr );
SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
print( "%% Loading Rom Image from '%s' to 0x%06X\n", fname, roms[i].loadaddr );
flushdisplay();
hFile = fopen( fname, "rb" );
if( hFile == NULL )
{
error( "Could not open \'%s\'.", fname );
wsprintf( sbbuf, "Could not open \'%s\'...", fname );
SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
st.readytogo = 0;
flushdisplay();
return( FALSE );
}
else
{
fseek( hFile, 0L, SEEK_END );
gamesize = ftell( hFile );
gamesize -= roms[i].offset;
fseek( hFile, roms[i].offset, SEEK_SET );
fread( st.ram + roms[i].loadaddr, 1, gamesize, hFile );
fclose( hFile );
}
// Byte Swap Game Rom
for( j = 0; j < gamesize; j+=2 )
{
tmp = st.ram[j+roms[i].loadaddr];
st.ram[j+roms[i].loadaddr] = st.ram[j+roms[i].loadaddr+1];
st.ram[j+roms[i].loadaddr+1] = tmp;
}
}
else
return( FALSE );
cfg.hres = roms[i].hres;
cfg.vres = roms[i].vres;
st.readytogo = 1;
boot_jaguar( roms[i].loadaddr );
return( TRUE );
}
////////////////////////////////////////////////////////////////////////////////
// Entry Point for Standard Cartridge Loading
void boot( char *cartname )
{
static char buf[MAX_PATH]; // Temporary Buffer
FILE *hFile; // Handle to File
dword gamesize; // Size of Loaded Game Rom
dword i; // Iterator
dword bootsize; // Size of Loaded Boot Rom
byte tmp; // Temporary Byte Storage
// Load Game Rom
strcpy( buf, cfg.rompath );
strcat( buf, cartname );
#ifdef DEBUG
print( "%% Loading Rom Image from '%s'\n", buf );
#endif
hFile = fopen( buf, "rb" );
if( hFile == NULL )
{
#ifdef DEBUG
error( "Could not open \'%s\'", buf );
#endif
st.readytogo = 0;
return;
}
else
{
fseek( hFile, 0L, SEEK_END );
gamesize = ftell( hFile );
fseek( hFile, 0L, SEEK_SET );
fread( st.game, 1, gamesize, hFile );
fclose( hFile );
}
// Byte Swap Game Rom
for( i = 0; i < gamesize; i+=2 )
{
tmp = st.game[i];
st.game[i] = st.game[i+1];
st.game[i+1] = tmp;
}
// Load Boot Rom
strcpy( buf, cfg.bootpath );
strcat( buf, "jagboot.rom" );
#ifdef DEBUG
print( "%% Loading Boot Rom Image \'%s\'\n", buf );
#endif
hFile = fopen( buf, "rb" );
if( hFile == NULL )
{
#ifdef DEBUG
error( "Could Not Open Boot Rom" );
print( "This file must be named 'jagboot.rom' and be located"
" in the 'Boot Path'\n" );
#endif
st.readytogo = 0;
return;
}
else
{
fseek( hFile, 0L, SEEK_END );
bootsize = ftell( hFile );
if( bootsize != 131072 )
{
fclose( hFile );
#ifdef DEBUG
error( "Invalid Boot Rom File Size" );
#endif
st.readytogo = 0;
return;
}
fseek( hFile, 0L, SEEK_SET );
fread( st.boot, 1, bootsize, hFile );
fclose( hFile );
}
// Byte Swap Boot Rom
for( i = 0; i < bootsize; i+=2 )
{
tmp = st.boot[i];
st.boot[i] = st.boot[i+1];
st.boot[i+1] = tmp;
}
// Copy Interrupt Stack Pointer and Initial PC to 0x000000
memcpy( st.ram, st.boot, 8 ); // Start of Boot Code
st.ram[5] = 0x00;
st.ram[4] = 0x80; // Start of Program Code
st.ram[7] = 0x20;
st.ram[6] = 0x00;
st.readytogo = 1;
boot_jaguar( 802000 );
}
////////////////////////////////////////////////////////////////////////////////
// Entry Point for Image Loading at RAM Memory Address (Demo Support)
void bootaddr( char *cartname, int address )
{
static char buf[MAX_PATH]; // Temporary Buffer
FILE *hFile; // Handle to File
dword bootsize; // Size of Loaded Boot Rom
dword gamesize; // Size of Loaded Game Rom
dword i; // Iterator
byte tmp; // Temporary Byte Storage
// Load Game Rom
strcpy( buf, cfg.rompath );
strcat( buf, cartname );
#ifdef DEBUG
print( "%% Loading Rom Image from '%s' to 0x%06X\n", buf, address );
#endif
hFile = fopen( buf, "rb" );
if( hFile == NULL )
{
#ifdef DEBUG
error( "Could not open \'%s\'", buf );
#endif
st.readytogo = 0;
return;
}
else
{
fseek( hFile, 0L, SEEK_END );
gamesize = ftell( hFile );
fseek( hFile, 0L, SEEK_SET );
fread( st.ram + address, 1, gamesize, hFile );
fclose( hFile );
}
// Byte Swap Game Rom
for( i = 0; i < gamesize; i+=2 )
{
tmp = st.ram[i+address];
st.ram[i+address] = st.ram[i+address+1];
st.ram[i+address+1] = tmp;
}
// Load Boot Rom
strcpy( buf, cfg.bootpath );
strcat( buf, "jagboot.rom" );
#ifdef DEBUG
print( "%% Loading Boot Rom Image \'%s\'\n", buf );
#endif
hFile = fopen( buf, "rb" );
if( hFile == NULL )
{
#ifdef DEBUG
error( "Could Not Open Boot Rom" );
print( "This file must be named 'jagboot.rom' and be located"
" in the 'Boot Path'\n" );
#endif
st.readytogo = 0;
return;
}
else
{
fseek( hFile, 0L, SEEK_END );
bootsize = ftell( hFile );
if( bootsize != 131072 )
{
fclose( hFile );
#ifdef DEBUG
error( "Invalid Boot Rom File Size" );
#endif
st.readytogo = 0;
return;
}
fseek( hFile, 0L, SEEK_SET );
fread( st.boot, 1, bootsize, hFile );
fclose( hFile );
}
// Byte Swap Boot Rom
for( i = 0; i < bootsize; i+=2 )
{
tmp = st.boot[i];
st.boot[i] = st.boot[i+1];
st.boot[i+1] = tmp;
}
st.readytogo = 1;
boot_jaguar( address );
}
////////////////////////////////////////////////////////////////////////////////
// Entry Point for CDROM Emulation
void bootcd( void )
{/*
static char buf[MAX_PATH]; // Temporary Buffer
FILE *hFile; // Handle to File
dword bootsize; // Size of Loaded Boot Rom
dword cdrsize; // Size of Loaded CD Boot Rom
dword i; // Iterator
byte tmp; // Temporary Byte Storage
// Load CD BIOS
strcpy( buf, cfg.bootpath );
strcat( buf, "jagcd.rom" );
#ifdef DEBUG
print( "%% Loading CD Boot Rom Image from '%s' to 0x%06X\n", buf, 0x00800000 );
#endif
hFile = fopen( buf, "rb" );
if( hFile == NULL )
{
#ifdef DEBUG
error( "Could not open \'%s\'", buf );
#endif
st.readytogo = 0;
return;
}
else
{
fseek( hFile, 0L, SEEK_END );
cdrsize = ftell( hFile );
fseek( hFile, 0L, SEEK_SET );
fread( st.game, 1, cdrsize, hFile );
fclose( hFile );
}
// Byte Swap Game Rom
for( i = 0; i < cdrsize; i+=2 )
{
tmp = st.game[i];
st.game[i] = st.game[i+1];
st.game[i+1] = tmp;
}
// Load Boot Rom
strcpy( buf, cfg.bootpath );
strcat( buf, "jagboot.rom" );
#ifdef DEBUG
print( "%% Loading Boot Rom Image \'%s\'\n", buf );
#endif
hFile = fopen( buf, "rb" );
if( hFile == NULL )
{
#ifdef DEBUG
error( "Could Not Open Boot Rom" );
print( "This file must be named 'jagboot.rom' and be located"
" in the 'Boot Path'\n" );
#endif
st.readytogo = 0;
return;
}
else
{
fseek( hFile, 0L, SEEK_END );
bootsize = ftell( hFile );
if( bootsize != 131072 )
{
fclose( hFile );
#ifdef DEBUG
error( "Invalid Boot Rom File Size" );
#endif
st.readytogo = 0;
return;
}
fseek( hFile, 0L, SEEK_SET );
fread( st.boot, 1, bootsize, hFile );
fclose( hFile );
}
// Byte Swap Boot Rom
for( i = 0; i < bootsize; i+=2 )
{
tmp = st.boot[i];
st.boot[i] = st.boot[i+1];
st.boot[i+1] = tmp;
}
st.readytogo = 1;
boot_jaguar();*/
}