2006-02-25 20:50:29 +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
2009-02-16 19:18:34 +00:00
Copyright ( C ) 2006 - 2009 , Tom Charlesworth , Michael Pohoreski
2006-02-25 20:50:29 +00:00
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: main
*
* Author : Various
*/
# include "StdAfx.h"
# pragma hdrstop
2009-02-16 19:18:34 +00:00
2008-02-22 21:28:35 +00:00
# include <objbase.h>
2007-08-06 21:38:35 +00:00
# include "MouseInterface.h"
2006-02-25 20:50:29 +00:00
2008-08-25 00:53:19 +00:00
char VERSIONSTRING [ 16 ] = " xx.yy.zz.ww " ;
2006-02-25 20:50:29 +00:00
2007-05-28 11:16:42 +00:00
TCHAR * g_pAppTitle = TITLE_APPLE_2E_ENHANCED ;
2006-06-27 02:34:46 +00:00
2007-05-28 11:16:42 +00:00
eApple2Type g_Apple2Type = A2TYPE_APPLE2EEHANCED ;
2006-06-12 22:06:50 +00:00
2006-02-25 20:50:29 +00:00
BOOL behind = 0 ; // Redundant
DWORD cumulativecycles = 0 ; // Wraps after ~1hr 9mins
DWORD cyclenum = 0 ; // Used by SpkrToggle() for non-wave sound
DWORD emulmsec = 0 ;
static DWORD emulmsec_frac = 0 ;
bool g_bFullSpeed = false ;
2006-07-02 09:56:50 +00:00
2008-06-20 23:47:25 +00:00
//Pravets 8A/C variables
bool P8CAPS_ON = false ;
bool P8Shift = false ;
//=================================================
2006-07-02 09:56:50 +00:00
// Win32
HINSTANCE g_hInstance = ( HINSTANCE ) 0 ;
2006-06-12 22:06:50 +00:00
AppMode_e g_nAppMode = MODE_LOGO ;
2006-02-25 20:50:29 +00:00
static int lastmode = MODE_LOGO ;
DWORD needsprecision = 0 ; // Redundant
2006-06-25 03:41:52 +00:00
TCHAR g_sProgramDir [ MAX_PATH ] = TEXT ( " " ) ;
TCHAR g_sCurrentDir [ MAX_PATH ] = TEXT ( " " ) ; // Also Starting Dir
2006-06-26 16:59:48 +00:00
bool g_bResetTiming = false ; // Redundant
2006-02-25 20:50:29 +00:00
BOOL restart = 0 ;
DWORD g_dwSpeed = SPEED_NORMAL ; // Affected by Config dialog's speed slider bar
double g_fCurrentCLK6502 = CLK_6502 ; // Affected by Config dialog's speed slider bar
static double g_fMHz = 1.0 ; // Affected by Config dialog's speed slider bar
int g_nCpuCyclesFeedback = 0 ;
2006-03-12 09:05:39 +00:00
DWORD g_dwCyclesThisFrame = 0 ;
2006-02-25 20:50:29 +00:00
FILE * g_fh = NULL ;
bool g_bDisableDirectSound = false ;
2007-08-06 21:38:35 +00:00
CSuperSerialCard sg_SSC ;
CMouseInterface sg_Mouse ;
2009-02-14 04:05:15 +00:00
// TODO: CLEANUP! Move to peripherals.cpp!!!
2008-08-19 21:36:31 +00:00
# ifdef SUPPORT_CPM
2009-01-06 22:02:31 +00:00
UINT g_Slot4 = CT_Empty ;
2008-08-19 21:36:31 +00:00
# else
2008-02-22 21:28:35 +00:00
UINT g_Slot4 = CT_Mockingboard ; // CT_Mockingboard or CT_MouseInterface
2008-08-19 21:36:31 +00:00
# endif
2009-01-06 22:02:31 +00:00
eCPU g_ActiveCPU = CPU_6502 ;
2008-02-22 21:28:35 +00:00
HANDLE g_hCustomRomF8 = INVALID_HANDLE_VALUE ; // Cmd-line specified custom ROM at $F800..$FFFF
static bool g_bCustomRomF8Failed = false ; // Set if custom ROM file failed
2007-05-28 11:16:42 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
# define DBG_CALC_FREQ 0
# if DBG_CALC_FREQ
const UINT MAX_CNT = 256 ;
double g_fDbg [ MAX_CNT ] ;
UINT g_nIdx = 0 ;
double g_fMeanPeriod , g_fMeanFreq ;
ULONGLONG g_nPerfFreq = 0 ;
# endif
//---------------------------------------------------------------------------
void ContinueExecution ( )
{
static BOOL pageflipping = 0 ; //?
const double fUsecPerSec = 1.e6 ;
# if 1
const UINT nExecutionPeriodUsec = 1000 ; // 1.0ms
// const UINT nExecutionPeriodUsec = 100; // 0.1ms
const double fExecutionPeriodClks = g_fCurrentCLK6502 * ( ( double ) nExecutionPeriodUsec / fUsecPerSec ) ;
# else
const double fExecutionPeriodClks = 1800.0 ;
const UINT nExecutionPeriodUsec = ( UINT ) ( fUsecPerSec * ( fExecutionPeriodClks / g_fCurrentCLK6502 ) ) ;
# endif
//
2007-08-06 21:38:35 +00:00
bool bScrollLock_FullSpeed = g_uScrollLockToggle
? g_bScrollLock_FullSpeed
: ( GetKeyState ( VK_SCROLL ) < 0 ) ;
2006-02-25 20:50:29 +00:00
g_bFullSpeed = ( ( g_dwSpeed = = SPEED_MAX ) | |
2007-08-06 21:38:35 +00:00
bScrollLock_FullSpeed | |
2006-02-25 20:50:29 +00:00
( DiskIsSpinning ( ) & & enhancedisk & & ! Spkr_IsActive ( ) & & ! MB_IsActive ( ) ) ) ;
if ( g_bFullSpeed )
{
// Don't call Spkr_Mute() - will get speaker clicks
MB_Mute ( ) ;
SysClk_StopTimer ( ) ;
g_nCpuCyclesFeedback = 0 ; // For the case when this is a big -ve number
}
else
{
// Don't call Spkr_Demute()
MB_Demute ( ) ;
SysClk_StartTimerUsec ( nExecutionPeriodUsec ) ;
}
//
int nCyclesToExecute = ( int ) fExecutionPeriodClks + g_nCpuCyclesFeedback ;
if ( nCyclesToExecute < 0 )
nCyclesToExecute = 0 ;
DWORD dwExecutedCycles = CpuExecute ( nCyclesToExecute ) ;
2006-03-12 09:05:39 +00:00
g_dwCyclesThisFrame + = dwExecutedCycles ;
2006-02-25 20:50:29 +00:00
//
cyclenum = dwExecutedCycles ;
DiskUpdatePosition ( dwExecutedCycles ) ;
JoyUpdatePosition ( ) ;
2006-03-12 09:05:39 +00:00
VideoUpdateVbl ( g_dwCyclesThisFrame ) ;
2006-02-25 20:50:29 +00:00
SpkrUpdate ( cyclenum ) ;
2007-05-28 11:16:42 +00:00
sg_SSC . CommUpdate ( cyclenum ) ;
2007-03-23 22:26:35 +00:00
PrintUpdate ( cyclenum ) ;
2006-02-25 20:50:29 +00:00
//
const DWORD CLKS_PER_MS = ( DWORD ) g_fCurrentCLK6502 / 1000 ;
emulmsec_frac + = dwExecutedCycles ;
if ( emulmsec_frac > CLKS_PER_MS )
{
emulmsec + = emulmsec_frac / CLKS_PER_MS ;
emulmsec_frac % = CLKS_PER_MS ;
}
//
// DETERMINE WHETHER THE SCREEN WAS UPDATED, THE DISK WAS SPINNING,
// OR THE KEYBOARD I/O PORTS WERE BEING EXCESSIVELY QUERIED THIS CLOCKTICK
VideoCheckPage ( 0 ) ;
BOOL screenupdated = VideoHasRefreshed ( ) ;
BOOL systemidle = 0 ; //(KeybGetNumQueries() > (clockgran << 2)); // && (!ranfinegrain); // TO DO
if ( screenupdated )
pageflipping = 3 ;
//
2006-03-12 09:05:39 +00:00
if ( g_dwCyclesThisFrame > = dwClksPerFrame )
2006-02-25 20:50:29 +00:00
{
2006-03-12 09:05:39 +00:00
g_dwCyclesThisFrame - = dwClksPerFrame ;
2006-02-25 20:50:29 +00:00
2006-06-12 22:06:50 +00:00
if ( g_nAppMode ! = MODE_LOGO )
2006-02-25 20:50:29 +00:00
{
VideoUpdateFlash ( ) ;
static BOOL anyupdates = 0 ;
static DWORD lastcycles = 0 ;
static BOOL lastupdates [ 2 ] = { 0 , 0 } ;
anyupdates | = screenupdated ;
//
lastcycles = cumulativecycles ;
if ( ( ! anyupdates ) & & ( ! lastupdates [ 0 ] ) & & ( ! lastupdates [ 1 ] ) & & VideoApparentlyDirty ( ) )
{
VideoCheckPage ( 1 ) ;
static DWORD lasttime = 0 ;
DWORD currtime = GetTickCount ( ) ;
if ( ( ! g_bFullSpeed ) | |
( currtime - lasttime > = ( DWORD ) ( ( graphicsmode | | ! systemidle ) ? 100 : 25 ) ) )
{
VideoRefreshScreen ( ) ;
lasttime = currtime ;
}
screenupdated = 1 ;
}
lastupdates [ 1 ] = lastupdates [ 0 ] ;
lastupdates [ 0 ] = anyupdates ;
anyupdates = 0 ;
if ( pageflipping )
pageflipping - - ;
}
2007-08-06 21:38:35 +00:00
MB_EndOfVideoFrame ( ) ;
2006-02-25 20:50:29 +00:00
}
//
if ( ! g_bFullSpeed )
{
SysClk_WaitTimer ( ) ;
# if DBG_CALC_FREQ
if ( g_nPerfFreq )
{
QueryPerformanceCounter ( ( LARGE_INTEGER * ) & nTime1 ) ;
LONGLONG nTimeDiff = nTime1 - nTime0 ;
double fTime = ( double ) nTimeDiff / ( double ) ( LONGLONG ) g_nPerfFreq ;
g_fDbg [ g_nIdx ] = fTime ;
g_nIdx = ( g_nIdx + 1 ) & ( MAX_CNT - 1 ) ;
g_fMeanPeriod = 0.0 ;
for ( UINT n = 0 ; n < MAX_CNT ; n + + )
g_fMeanPeriod + = g_fDbg [ n ] ;
g_fMeanPeriod / = ( double ) MAX_CNT ;
g_fMeanFreq = 1.0 / g_fMeanPeriod ;
}
# endif
}
}
//===========================================================================
void SetCurrentCLK6502 ( )
{
static DWORD dwPrevSpeed = ( DWORD ) - 1 ;
if ( dwPrevSpeed = = g_dwSpeed )
return ;
dwPrevSpeed = g_dwSpeed ;
// SPEED_MIN = 0 = 0.50 MHz
// SPEED_NORMAL = 10 = 1.00 MHz
// 20 = 2.00 MHz
// SPEED_MAX-1 = 39 = 3.90 MHz
// SPEED_MAX = 40 = ???? MHz (run full-speed, /g_fCurrentCLK6502/ is ignored)
if ( g_dwSpeed < SPEED_NORMAL )
g_fMHz = 0.5 + ( double ) g_dwSpeed * 0.05 ;
else
g_fMHz = ( double ) g_dwSpeed / 10.0 ;
g_fCurrentCLK6502 = CLK_6502 * g_fMHz ;
//
// Now re-init modules that are dependent on /g_fCurrentCLK6502/
//
SpkrReinitialize ( ) ;
MB_Reinitialize ( ) ;
}
//===========================================================================
LRESULT CALLBACK DlgProc ( HWND window ,
UINT message ,
WPARAM wparam ,
LPARAM lparam ) {
if ( message = = WM_CREATE ) {
RECT rect ;
GetWindowRect ( window , & rect ) ;
SIZE size ;
size . cx = rect . right - rect . left ;
size . cy = rect . bottom - rect . top ;
rect . left = ( GetSystemMetrics ( SM_CXSCREEN ) - size . cx ) > > 1 ;
rect . top = ( GetSystemMetrics ( SM_CYSCREEN ) - size . cy ) > > 1 ;
rect . right = rect . left + size . cx ;
rect . bottom = rect . top + size . cy ;
MoveWindow ( window ,
rect . left ,
rect . top ,
rect . right - rect . left ,
rect . bottom - rect . top ,
0 ) ;
ShowWindow ( window , SW_SHOW ) ;
}
return DefWindowProc ( window , message , wparam , lparam ) ;
}
//===========================================================================
2006-06-12 22:06:50 +00:00
void EnterMessageLoop ( )
{
MSG message ;
2007-03-27 20:46:14 +00:00
PeekMessage ( & message , NULL , 0 , 0 , PM_NOREMOVE ) ;
2006-07-05 21:23:13 +00:00
while ( message . message ! = WM_QUIT )
{
2007-03-27 20:46:14 +00:00
if ( PeekMessage ( & message , NULL , 0 , 0 , PM_REMOVE ) )
2006-06-12 22:06:50 +00:00
{
2007-03-27 20:46:14 +00:00
TranslateMessage ( & message ) ;
DispatchMessage ( & message ) ;
while ( ( g_nAppMode = = MODE_RUNNING ) | | ( g_nAppMode = = MODE_STEPPING ) )
2006-06-12 22:06:50 +00:00
{
2007-03-27 20:46:14 +00:00
if ( PeekMessage ( & message , 0 , 0 , 0 , PM_REMOVE ) )
{
if ( message . message = = WM_QUIT )
return ;
TranslateMessage ( & message ) ;
DispatchMessage ( & message ) ;
}
else if ( g_nAppMode = = MODE_STEPPING )
{
DebugContinueStepping ( ) ;
}
else
{
ContinueExecution ( ) ;
if ( g_nAppMode ! = MODE_DEBUG )
{
if ( g_bFullSpeed )
ContinueExecution ( ) ;
}
}
2006-06-12 22:06:50 +00:00
}
}
2007-03-27 20:46:14 +00:00
else
2007-03-23 22:26:35 +00:00
{
2007-03-27 20:46:14 +00:00
if ( g_nAppMode = = MODE_DEBUG )
DebuggerUpdate ( ) ;
else if ( g_nAppMode = = MODE_LOGO )
Sleep ( 100 ) ; // Stop process hogging CPU
2007-03-23 22:26:35 +00:00
}
2006-07-05 21:23:13 +00:00
}
}
2006-06-12 22:06:50 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
void GetProgramDirectory ( ) {
2006-06-25 03:41:52 +00:00
GetModuleFileName ( ( HINSTANCE ) 0 , g_sProgramDir , MAX_PATH ) ;
g_sProgramDir [ MAX_PATH - 1 ] = 0 ;
int loop = _tcslen ( g_sProgramDir ) ;
2006-02-25 20:50:29 +00:00
while ( loop - - )
2006-06-25 03:41:52 +00:00
if ( ( g_sProgramDir [ loop ] = = TEXT ( ' \\ ' ) ) | |
( g_sProgramDir [ loop ] = = TEXT ( ' : ' ) ) ) {
g_sProgramDir [ loop + 1 ] = 0 ;
2006-02-25 20:50:29 +00:00
break ;
}
}
//===========================================================================
2008-06-20 23:47:25 +00:00
//Reads configuration from the registry entries
2007-05-28 11:16:42 +00:00
void LoadConfiguration ( )
{
DWORD dwComputerType ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_APPLE2_TYPE ) , & dwComputerType ) )
2007-05-28 11:16:42 +00:00
{
2009-01-09 23:27:29 +00:00
REGLOAD ( TEXT ( REGVALUE_CLONETYPE ) , & g_uCloneType ) ;
2008-06-20 23:47:25 +00:00
if ( ( dwComputerType > = A2TYPE_MAX ) | | ( dwComputerType > = A2TYPE_UNDEFINED & & dwComputerType < A2TYPE_CLONE ) )
2007-05-28 11:16:42 +00:00
dwComputerType = A2TYPE_APPLE2EEHANCED ;
2008-06-20 23:47:25 +00:00
if ( dwComputerType = = A2TYPE_CLONE )
{
switch ( g_uCloneType )
{
case 0 : g_Apple2Type = A2TYPE_PRAVETS82 ; break ;
2009-01-09 21:59:22 +00:00
case 1 : g_Apple2Type = A2TYPE_PRAVETS8M ; break ;
case 2 : g_Apple2Type = A2TYPE_PRAVETS8A ; break ;
2008-06-20 23:47:25 +00:00
default : g_Apple2Type = A2TYPE_APPLE2EEHANCED ; break ;
}
}
else
{
g_Apple2Type = ( eApple2Type ) dwComputerType ;
}
2007-05-28 11:16:42 +00:00
}
2008-06-20 23:47:25 +00:00
else // Support older AppleWin registry entries
2007-05-28 11:16:42 +00:00
{
2009-01-09 23:27:29 +00:00
REGLOAD ( TEXT ( " Computer Emulation " ) , & dwComputerType ) ;
2007-05-28 11:16:42 +00:00
switch ( dwComputerType )
{
2008-06-20 23:47:25 +00:00
// NB. No A2TYPE_APPLE2E (this is correct)
2007-05-28 11:16:42 +00:00
case 0 : g_Apple2Type = A2TYPE_APPLE2 ;
case 1 : g_Apple2Type = A2TYPE_APPLE2PLUS ;
case 2 : g_Apple2Type = A2TYPE_APPLE2EEHANCED ;
default : g_Apple2Type = A2TYPE_APPLE2EEHANCED ;
}
}
2008-06-20 23:47:25 +00:00
switch ( g_Apple2Type ) //Sets the character set for the Apple model/clone
{
case A2TYPE_APPLE2 : g_nCharsetType = 0 ; break ;
case A2TYPE_APPLE2PLUS : g_nCharsetType = 0 ; break ;
case A2TYPE_APPLE2E : g_nCharsetType = 0 ; break ;
case A2TYPE_APPLE2EEHANCED : g_nCharsetType = 0 ; break ;
case A2TYPE_PRAVETS82 : g_nCharsetType = 1 ; break ;
case A2TYPE_PRAVETS8A : g_nCharsetType = 2 ; break ;
2009-01-09 21:59:22 +00:00
case A2TYPE_PRAVETS8M : g_nCharsetType = 3 ; break ; //This charset has a very small difference with the PRAVETS82 one an probably has some misplaced characters. Still the Pravets82 charset is used, because settiong charset to 3 results in some problems.
2008-06-20 23:47:25 +00:00
}
2008-04-11 21:54:06 +00:00
2009-01-09 23:27:29 +00:00
REGLOAD ( TEXT ( " Joystick 0 Emulation " ) , & joytype [ 0 ] ) ;
REGLOAD ( TEXT ( " Joystick 1 Emulation " ) , & joytype [ 1 ] ) ;
REGLOAD ( TEXT ( " Sound Emulation " ) , & soundtype ) ;
2007-05-28 11:16:42 +00:00
DWORD dwSerialPort ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( " Serial Port " ) , & dwSerialPort ) )
2008-11-25 22:33:05 +00:00
sg_SSC . SetSerialPort ( dwSerialPort ) ;
2007-05-28 11:16:42 +00:00
2009-02-14 04:05:15 +00:00
REGLOAD ( TEXT ( " Emulation Speed " ) , & g_dwSpeed ) ;
REGLOAD ( TEXT ( " Enhance Disk Speed " ) , ( DWORD * ) & enhancedisk ) ;
Config_Load_Video ( ) ;
REGLOAD ( TEXT ( " Uthernet Active " ) , ( DWORD * ) & tfe_enabled ) ;
2006-02-25 20:50:29 +00:00
SetCurrentCLK6502 ( ) ;
//
DWORD dwTmp ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_THE_FREEZES_F8_ROM ) , & dwTmp ) )
2008-02-22 21:28:35 +00:00
g_uTheFreezesF8Rom = dwTmp ;
2007-08-06 21:38:35 +00:00
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_SPKR_VOLUME ) , & dwTmp ) )
2006-02-25 20:50:29 +00:00
SpkrSetVolume ( dwTmp , PSP_GetVolumeMax ( ) ) ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_MB_VOLUME ) , & dwTmp ) )
2006-02-25 20:50:29 +00:00
MB_SetVolume ( dwTmp , PSP_GetVolumeMax ( ) ) ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_SOUNDCARD_TYPE ) , & dwTmp ) )
2006-02-25 20:50:29 +00:00
MB_SetSoundcardType ( ( eSOUNDCARDTYPE ) dwTmp ) ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_SAVE_STATE_ON_EXIT ) , & dwTmp ) )
2006-02-25 20:50:29 +00:00
g_bSaveStateOnExit = dwTmp ? true : false ;
2009-01-09 21:59:22 +00:00
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_DUMP_TO_PRINTER ) , & dwTmp ) )
2009-01-09 21:59:22 +00:00
g_bDumpToPrinter = dwTmp ? true : false ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_CONVERT_ENCODING ) , & dwTmp ) )
2009-01-09 21:59:22 +00:00
g_bConvertEncoding = dwTmp ? true : false ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_FILTER_UNPRINTABLE ) , & dwTmp ) )
2009-01-09 21:59:22 +00:00
g_bFilterUnprintable = dwTmp ? true : false ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_PRINTER_APPEND ) , & dwTmp ) )
2009-01-09 21:59:22 +00:00
g_bPrinterAppend = dwTmp ? true : false ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_HDD_ENABLED ) , & dwTmp ) )
2006-02-25 20:50:29 +00:00
HD_SetEnabled ( dwTmp ? true : false ) ;
char szHDFilename [ MAX_PATH ] = { 0 } ;
2008-08-31 04:31:35 +00:00
if ( RegLoadString ( TEXT ( REG_CONFIG ) , TEXT ( REGVALUE_HDD_IMAGE1 ) , 1 , szHDFilename , sizeof ( szHDFilename ) ) )
2006-02-25 20:50:29 +00:00
HD_InsertDisk2 ( 0 , szHDFilename ) ;
2008-08-31 04:31:35 +00:00
if ( RegLoadString ( TEXT ( REG_CONFIG ) , TEXT ( REGVALUE_HDD_IMAGE2 ) , 1 , szHDFilename , sizeof ( szHDFilename ) ) )
2006-02-25 20:50:29 +00:00
HD_InsertDisk2 ( 1 , szHDFilename ) ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_PDL_XTRIM ) , & dwTmp ) )
2006-02-25 20:50:29 +00:00
JoySetTrim ( ( short ) dwTmp , true ) ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_PDL_YTRIM ) , & dwTmp ) )
2006-02-25 20:50:29 +00:00
JoySetTrim ( ( short ) dwTmp , false ) ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_SCROLLLOCK_TOGGLE ) , & dwTmp ) )
2007-08-06 21:38:35 +00:00
g_uScrollLockToggle = dwTmp ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_MOUSE_IN_SLOT4 ) , & dwTmp ) )
2008-02-22 21:28:35 +00:00
g_uMouseInSlot4 = dwTmp ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_MOUSE_CROSSHAIR ) , & dwTmp ) )
2008-05-17 23:20:33 +00:00
g_uMouseShowCrosshair = dwTmp ;
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_MOUSE_RESTRICT_TO_WINDOW ) , & dwTmp ) )
2008-05-18 18:23:25 +00:00
g_uMouseRestrictToWindow = dwTmp ;
2008-08-19 21:36:31 +00:00
# ifdef SUPPORT_CPM
2009-01-09 23:27:29 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_Z80_IN_SLOT5 ) , & dwTmp ) )
2009-01-06 22:02:31 +00:00
g_uZ80InSlot5 = dwTmp ;
if ( g_uZ80InSlot5 )
MB_SetSoundcardType ( SC_NONE ) ;
2009-02-14 04:05:15 +00:00
g_Slot4 =
g_uMouseInSlot4 ? CT_MouseInterface
: g_uZ80InSlot5 ? CT_Empty
: CT_Mockingboard ;
// : g_uClockInSlot4 ? CT_GenericClock
// : CT_Mockingboard;
2009-01-06 22:02:31 +00:00
# else
2009-02-14 04:05:15 +00:00
g_Slot4 = g_uMouseInSlot4
? CT_MouseInterface
: CT_Mockingboard ;
2008-08-19 21:36:31 +00:00
# endif
2009-01-06 22:02:31 +00:00
2006-02-25 20:50:29 +00:00
//
2009-01-06 22:02:31 +00:00
char szFilename [ MAX_PATH ] = { 0 } ;
RegLoadString ( TEXT ( REG_CONFIG ) , TEXT ( REGVALUE_SAVESTATE_FILENAME ) , 1 , szFilename , sizeof ( szFilename ) ) ;
Snapshot_SetFilename ( szFilename ) ; // If not in Registry than default will be used
2009-01-09 21:59:22 +00:00
szFilename [ 0 ] = 0 ;
RegLoadString ( TEXT ( REG_CONFIG ) , TEXT ( REGVALUE_PRINTER_FILENAME ) , 1 , szFilename , sizeof ( szFilename ) ) ;
Printer_SetFilename ( szFilename ) ; // If not in Registry than default will be used
2009-01-06 22:02:31 +00:00
// Current/Starting Dir is the "root" of where the user keeps his disk images
RegLoadString ( TEXT ( REG_PREFS ) , TEXT ( REGVALUE_PREF_START_DIR ) , 1 , g_sCurrentDir , MAX_PATH ) ;
SetCurrentImageDir ( ) ;
Disk_LoadLastDiskImage ( 0 ) ;
Disk_LoadLastDiskImage ( 1 ) ;
2009-01-09 21:59:22 +00:00
dwTmp = 10 ;
2009-01-09 23:27:29 +00:00
REGLOAD ( TEXT ( REGVALUE_PRINTER_IDLE_LIMIT ) , & dwTmp ) ;
2009-01-09 21:59:22 +00:00
Printer_SetIdleLimit ( dwTmp ) ;
2009-01-06 22:02:31 +00:00
char szUthernetInt [ MAX_PATH ] = { 0 } ;
RegLoadString ( TEXT ( REG_CONFIG ) , TEXT ( " Uthernet Interface " ) , 1 , szUthernetInt , MAX_PATH ) ;
update_tfe_interface ( szUthernetInt , NULL ) ;
}
2006-02-25 20:50:29 +00:00
2009-01-06 22:02:31 +00:00
//===========================================================================
2008-06-21 11:48:15 +00:00
2009-01-06 22:02:31 +00:00
void SetCurrentImageDir ( )
{
SetCurrentDirectory ( g_sCurrentDir ) ;
2008-06-21 11:48:15 +00:00
}
2009-02-14 04:05:15 +00:00
// TODO: Added dialog option of which file extensions to registry
bool g_bRegisterFileTypes = true ;
bool g_bRegistryFileBin = false ;
bool g_bRegistryFileDo = true ;
bool g_bRegistryFileDsk = true ;
bool g_bRegistryFileNib = true ;
bool g_bRegistryFilePo = true ;
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-05-02 21:56:28 +00:00
void RegisterExtensions ( )
{
TCHAR szCommandTmp [ MAX_PATH ] ;
GetModuleFileName ( ( HMODULE ) 0 , szCommandTmp , MAX_PATH ) ;
2009-02-14 04:05:15 +00:00
# if TEST_REG_BUG
TCHAR command [ MAX_PATH ] ;
wsprintf ( command , " %s " , szCommandTmp ) ; // Wrap path & filename in quotes & null terminate
TCHAR icon [ MAX_PATH ] ;
wsprintf ( icon , TEXT ( " \" %s,1 \" " ) , ( LPCTSTR ) command ) ;
# endif
2006-05-02 21:56:28 +00:00
TCHAR command [ MAX_PATH ] ;
wsprintf ( command , " \" %s \" " , szCommandTmp ) ; // Wrap path & filename in quotes & null terminate
TCHAR icon [ MAX_PATH ] ;
wsprintf ( icon , TEXT ( " %s,1 " ) , ( LPCTSTR ) command ) ;
_tcscat ( command , TEXT ( " \" %1 \" " ) ) ; // Append "%1"
2009-02-14 04:05:15 +00:00
// _tcscat(command,TEXT("-d1 %1\"")); // Append "%1"
// sprintf(command, "\"%s\" \"-d1 %%1\"", szCommandTmp); // Wrap path & filename in quotes & null terminate
2006-05-02 21:56:28 +00:00
RegSetValue ( HKEY_CLASSES_ROOT , " .bin " , REG_SZ , " DiskImage " , 10 ) ;
RegSetValue ( HKEY_CLASSES_ROOT , " .do " , REG_SZ , " DiskImage " , 10 ) ;
RegSetValue ( HKEY_CLASSES_ROOT , " .dsk " , REG_SZ , " DiskImage " , 10 ) ;
RegSetValue ( HKEY_CLASSES_ROOT , " .nib " , REG_SZ , " DiskImage " , 10 ) ;
RegSetValue ( HKEY_CLASSES_ROOT , " .po " , REG_SZ , " DiskImage " , 10 ) ;
// RegSetValue(HKEY_CLASSES_ROOT,".aws",REG_SZ,"DiskImage",10); // TO DO
// RegSetValue(HKEY_CLASSES_ROOT,".hdv",REG_SZ,"DiskImage",10); // TO DO
RegSetValue ( HKEY_CLASSES_ROOT ,
" DiskImage " ,
REG_SZ , " Disk Image " , 21 ) ;
RegSetValue ( HKEY_CLASSES_ROOT ,
" DiskImage \\ DefaultIcon " ,
REG_SZ , icon , _tcslen ( icon ) + 1 ) ;
2009-02-14 04:05:15 +00:00
// This key can interfere....
// HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExt\.dsk
2006-05-02 21:56:28 +00:00
RegSetValue ( HKEY_CLASSES_ROOT ,
" DiskImage \\ shell \\ open \\ command " ,
REG_SZ , command , _tcslen ( command ) + 1 ) ;
RegSetValue ( HKEY_CLASSES_ROOT ,
" DiskImage \\ shell \\ open \\ ddeexec " ,
REG_SZ , " %1 " , 3 ) ;
RegSetValue ( HKEY_CLASSES_ROOT ,
" DiskImage \\ shell \\ open \\ ddeexec \\ application " ,
2009-02-14 04:05:15 +00:00
REG_SZ , " applewin " , _tcslen ( " applewin " ) + 1 ) ;
// REG_SZ,szCommandTmp,_tcslen(szCommandTmp)+1);
2006-05-02 21:56:28 +00:00
RegSetValue ( HKEY_CLASSES_ROOT ,
" DiskImage \\ shell \\ open \\ ddeexec \\ topic " ,
2009-02-14 04:05:15 +00:00
REG_SZ , " system " , _tcslen ( " system " ) + 1 ) ;
2006-02-25 20:50:29 +00:00
}
2008-07-14 16:02:44 +00:00
//===========================================================================
2009-01-06 22:02:31 +00:00
void AppleWin_RegisterHotKeys ( )
{
BOOL bStatus = true ;
bStatus & = RegisterHotKey (
g_hFrameWindow , // HWND hWnd
VK_SNAPSHOT_560 , // int id (user/custom id)
0 , // UINT fsModifiers
VK_SNAPSHOT // UINT vk = PrintScreen
) ;
bStatus & = RegisterHotKey (
g_hFrameWindow , // HWND hWnd
VK_SNAPSHOT_280 , // int id (user/custom id)
MOD_SHIFT , // UINT fsModifiers
VK_SNAPSHOT // UINT vk = PrintScreen
) ;
if ( ! bStatus )
{
MessageBox ( g_hFrameWindow , " Unable to capture PrintScreen key " , " Warning " , MB_OK ) ;
}
}
//===========================================================================
2008-02-22 21:28:35 +00:00
LPSTR GetCurrArg ( LPSTR lpCmdLine )
{
if ( * lpCmdLine = = ' \" ' )
lpCmdLine + + ;
return lpCmdLine ;
}
2006-02-25 20:50:29 +00:00
LPSTR GetNextArg ( LPSTR lpCmdLine )
{
2009-02-14 04:05:15 +00:00
LPSTR pSrc = lpCmdLine ;
2006-02-25 20:50:29 +00:00
int bInQuotes = 0 ;
while ( * lpCmdLine )
{
if ( * lpCmdLine = = ' \" ' )
{
bInQuotes ^ = 1 ;
2009-02-14 04:05:15 +00:00
if ( bInQuotes )
{
}
2006-02-25 20:50:29 +00:00
if ( ! bInQuotes )
{
2009-02-14 04:05:15 +00:00
//MessageBox( NULL, lpCmdLine, pSrc, MB_OK );
2006-02-25 20:50:29 +00:00
* lpCmdLine + + = 0x00 ; // Assume end-quote is end of this arg
continue ;
}
}
if ( ( * lpCmdLine = = ' ' ) & & ! bInQuotes )
{
* lpCmdLine + + = 0x00 ;
break ;
}
lpCmdLine + + ;
}
return lpCmdLine ;
}
//---------------------------------------------------------------------------
int DoDiskInsert ( int nDrive , LPSTR szFileName )
{
DWORD dwAttributes = GetFileAttributes ( szFileName ) ;
if ( dwAttributes = = INVALID_FILE_ATTRIBUTES )
{
return - 1 ;
}
BOOL bWriteProtected = ( dwAttributes & FILE_ATTRIBUTE_READONLY ) ? TRUE : FALSE ;
return DiskInsert ( nDrive , szFileName , bWriteProtected , 0 ) ;
}
//---------------------------------------------------------------------------
int APIENTRY WinMain ( HINSTANCE passinstance , HINSTANCE , LPSTR lpCmdLine , int )
{
bool bSetFullScreen = false ;
bool bBoot = false ;
LPSTR szImageName_drive1 = NULL ;
LPSTR szImageName_drive2 = NULL ;
while ( * lpCmdLine )
{
LPSTR lpNextArg = GetNextArg ( lpCmdLine ) ;
2009-02-14 04:05:15 +00:00
// BUG: Double-click .DSK
// Think the 1st double quote is active, while the last double quote is getting stripped
//MessageBox(NULL, lpCmdLine, "Command Line", MB_OK );
if ( strcmp ( lpCmdLine , " -noreg " ) = = 0 )
{
g_bRegisterFileTypes = false ;
}
else
2006-02-25 20:50:29 +00:00
if ( strcmp ( lpCmdLine , " -d1 " ) = = 0 )
{
2008-02-22 21:28:35 +00:00
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
2006-02-25 20:50:29 +00:00
szImageName_drive1 = lpCmdLine ;
}
else if ( strcmp ( lpCmdLine , " -d2 " ) = = 0 )
{
2008-02-22 21:28:35 +00:00
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
2006-02-25 20:50:29 +00:00
szImageName_drive2 = lpCmdLine ;
}
else if ( strcmp ( lpCmdLine , " -f " ) = = 0 )
{
bSetFullScreen = true ;
}
else if ( ( strcmp ( lpCmdLine , " -l " ) = = 0 ) & & ( g_fh = = NULL ) )
{
2006-06-12 22:06:50 +00:00
g_fh = fopen ( " AppleWin.log " , " a+t " ) ; // Open log file (append & text g_nAppMode)
2006-02-25 20:50:29 +00:00
CHAR aDateStr [ 80 ] , aTimeStr [ 80 ] ;
GetDateFormat ( LOCALE_SYSTEM_DEFAULT , 0 , NULL , NULL , ( LPTSTR ) aDateStr , sizeof ( aDateStr ) ) ;
GetTimeFormat ( LOCALE_SYSTEM_DEFAULT , 0 , NULL , NULL , ( LPTSTR ) aTimeStr , sizeof ( aTimeStr ) ) ;
fprintf ( g_fh , " *** Logging started: %s %s \n " , aDateStr , aTimeStr ) ;
}
else if ( strcmp ( lpCmdLine , " -m " ) = = 0 )
{
g_bDisableDirectSound = true ;
}
# ifdef RAMWORKS
else if ( strcmp ( lpCmdLine , " -r " ) = = 0 ) // RamWorks size [1..127]
{
2008-02-22 21:28:35 +00:00
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
2006-02-25 20:50:29 +00:00
g_uMaxExPages = atoi ( lpCmdLine ) ;
if ( g_uMaxExPages > 127 )
g_uMaxExPages = 128 ;
else if ( g_uMaxExPages < 1 )
g_uMaxExPages = 1 ;
}
# endif
2008-02-22 21:28:35 +00:00
else if ( strcmp ( lpCmdLine , " -f8rom " ) = = 0 ) // Use custom 2K ROM at [$F800..$FFFF]
{
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
g_hCustomRomF8 = CreateFile ( lpCmdLine , GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_READONLY , NULL ) ;
if ( ( g_hCustomRomF8 = = INVALID_HANDLE_VALUE ) | | ( GetFileSize ( g_hCustomRomF8 , NULL ) ! = 0x800 ) )
g_bCustomRomF8Failed = true ;
}
2009-02-01 20:32:05 +00:00
else if ( strcmp ( lpCmdLine , " -printscreen " ) = = 0 ) // Turn on display of the last filename print screen was saved to
2009-01-06 22:02:31 +00:00
{
g_bDisplayPrintScreenFileName = true ;
}
2009-02-01 20:32:05 +00:00
else if ( strcmp ( lpCmdLine , " -use-real-printer " ) = = 0 ) // Enable control in Advanced config to allow dumping to a real printer
2009-01-17 15:10:00 +00:00
{
g_bEnableDumpToRealPrinter = true ;
}
2009-01-06 22:02:31 +00:00
2006-02-25 20:50:29 +00:00
lpCmdLine = lpNextArg ;
}
#if 0
# ifdef RIFF_SPKR
RiffInitWriteFile ( " Spkr.wav " , SPKR_SAMPLE_RATE , 1 ) ;
# endif
# ifdef RIFF_MB
RiffInitWriteFile ( " Mockingboard.wav " , 44100 , 2 ) ;
# endif
# endif
//-----
char szPath [ _MAX_PATH ] ;
if ( 0 = = GetModuleFileName ( NULL , szPath , sizeof ( szPath ) ) )
{
strcpy ( szPath , __argv [ 0 ] ) ;
}
// Extract application version and store in a global variable
DWORD dwHandle , dwVerInfoSize ;
dwVerInfoSize = GetFileVersionInfoSize ( szPath , & dwHandle ) ;
if ( dwVerInfoSize > 0 )
{
char * pVerInfoBlock = new char [ dwVerInfoSize ] ;
if ( GetFileVersionInfo ( szPath , NULL , dwVerInfoSize , pVerInfoBlock ) )
{
VS_FIXEDFILEINFO * pFixedFileInfo ;
UINT pFixedFileInfoLen ;
VerQueryValue ( pVerInfoBlock , TEXT ( " \\ " ) , ( LPVOID * ) & pFixedFileInfo , ( PUINT ) & pFixedFileInfoLen ) ;
// Construct version string from fixed file info block
unsigned long major = pFixedFileInfo - > dwFileVersionMS > > 16 ;
unsigned long minor = pFixedFileInfo - > dwFileVersionMS & 0xffff ;
unsigned long fix = pFixedFileInfo - > dwFileVersionLS > > 16 ;
unsigned long fix_minor = pFixedFileInfo - > dwFileVersionLS & 0xffff ;
2009-01-06 22:02:31 +00:00
sprintf ( VERSIONSTRING , " %d.%d.%d.%d " , major , minor , fix , fix_minor ) ; // potential buffer overflow
2006-02-25 20:50:29 +00:00
}
}
# if DBG_CALC_FREQ
QueryPerformanceFrequency ( ( LARGE_INTEGER * ) & g_nPerfFreq ) ;
if ( g_fh ) fprintf ( g_fh , " Performance frequency = %d \n " , g_nPerfFreq ) ;
# endif
//-----
2008-02-22 21:28:35 +00:00
// Initialize COM - so we can use CoCreateInstance
2008-05-17 23:20:33 +00:00
// . NB. DSInit() & DIMouse::DirectInputInit are done when g_hFrameWindow is created (WM_CREATE)
2008-02-22 21:28:35 +00:00
CoInitializeEx ( NULL , COINIT_APARTMENTTHREADED ) ;
2007-03-26 21:27:29 +00:00
bool bSysClkOK = SysClk_InitTimer ( ) ;
2006-02-25 20:50:29 +00:00
// DO ONE-TIME INITIALIZATION
2006-07-02 09:56:50 +00:00
g_hInstance = passinstance ;
2007-05-28 11:16:42 +00:00
MemPreInitialize ( ) ; // Call before any of the slot devices are initialized
2006-02-25 20:50:29 +00:00
GdiSetBatchLimit ( 512 ) ;
GetProgramDirectory ( ) ;
2009-02-14 04:05:15 +00:00
if ( g_bRegisterFileTypes )
{
RegisterExtensions ( ) ;
}
2006-02-25 20:50:29 +00:00
FrameRegisterClass ( ) ;
ImageInitialize ( ) ;
DiskInitialize ( ) ;
2006-06-12 22:06:50 +00:00
CreateColorMixMap ( ) ; // For tv emulation g_nAppMode
2006-02-25 20:50:29 +00:00
2009-02-14 04:05:15 +00:00
// BUG: Double-click .DSK
//MessageBox( NULL, szImageName_drive1, "Disk 1", MB_OK );
//MessageBox( NULL, szImageName_drive2, "Disk 2", MB_OK );
2006-02-25 20:50:29 +00:00
int nError = 0 ;
if ( szImageName_drive1 )
{
nError = DoDiskInsert ( 0 , szImageName_drive1 ) ;
2009-02-14 04:05:15 +00:00
FrameRefreshStatus ( DRAW_LEDS | DRAW_BUTTON_DRIVES ) ;
2006-02-25 20:50:29 +00:00
bBoot = true ;
}
if ( szImageName_drive2 )
{
nError | = DoDiskInsert ( 1 , szImageName_drive2 ) ;
}
//
do
{
// DO INITIALIZATION THAT MUST BE REPEATED FOR A RESTART
restart = 0 ;
2007-05-28 11:16:42 +00:00
g_nAppMode = MODE_LOGO ;
2006-02-25 20:50:29 +00:00
LoadConfiguration ( ) ;
DebugInitialize ( ) ;
JoyInitialize ( ) ;
MemInitialize ( ) ;
2009-02-16 19:18:34 +00:00
VideoInitialize ( ) ; // g_pFramebufferinfo been created now
2006-02-25 20:50:29 +00:00
FrameCreateWindow ( ) ;
2008-08-25 00:53:19 +00:00
// PrintScrn support
2009-01-06 22:02:31 +00:00
AppleWin_RegisterHotKeys ( ) ; // needs valid g_hFrameWindow
2008-07-14 16:02:44 +00:00
2008-02-22 21:28:35 +00:00
// Need to test if it's safe to call ResetMachineState(). In the meantime, just call DiskReset():
DiskReset ( ) ; // Switch from a booting A][+ to a non-autostart A][, so need to turn off floppy motor
2007-03-26 21:27:29 +00:00
if ( ! bSysClkOK )
{
MessageBox ( g_hFrameWindow , " DirectX failed to create SystemClock instance " , TEXT ( " AppleWin Error " ) , MB_OK ) ;
2007-03-27 20:46:14 +00:00
PostMessage ( g_hFrameWindow , WM_DESTROY , 0 , 0 ) ; // Close everything down
2007-03-26 21:27:29 +00:00
}
2008-02-22 21:28:35 +00:00
if ( g_bCustomRomF8Failed )
{
MessageBox ( g_hFrameWindow , " Failed to load custom F8 rom (not found or not exactly 2KB) " , TEXT ( " AppleWin Error " ) , MB_OK ) ;
PostMessage ( g_hFrameWindow , WM_DESTROY , 0 , 0 ) ; // Close everything down
}
2007-03-26 21:27:29 +00:00
tfe_init ( ) ;
2009-02-14 04:05:15 +00:00
Snapshot_Startup ( ) ; // Do this after everything has been init'ed
2006-02-25 20:50:29 +00:00
if ( bSetFullScreen )
{
2006-05-14 00:44:38 +00:00
PostMessage ( g_hFrameWindow , WM_KEYDOWN , VK_F1 + BTN_FULLSCR , 0 ) ;
PostMessage ( g_hFrameWindow , WM_KEYUP , VK_F1 + BTN_FULLSCR , 0 ) ;
2006-02-25 20:50:29 +00:00
bSetFullScreen = false ;
}
if ( bBoot )
{
2006-05-14 00:44:38 +00:00
PostMessage ( g_hFrameWindow , WM_KEYDOWN , VK_F1 + BTN_RUN , 0 ) ;
PostMessage ( g_hFrameWindow , WM_KEYUP , VK_F1 + BTN_RUN , 0 ) ;
2006-02-25 20:50:29 +00:00
bBoot = false ;
}
// ENTER THE MAIN MESSAGE LOOP
EnterMessageLoop ( ) ;
2007-08-06 21:38:35 +00:00
2006-02-25 20:50:29 +00:00
MB_Reset ( ) ;
2007-08-06 21:38:35 +00:00
sg_Mouse . Uninitialize ( ) ; // Maybe restarting due to switching slot-4 card from mouse to MB
2006-02-25 20:50:29 +00:00
}
while ( restart ) ;
// Release COM
DSUninit ( ) ;
SysClk_UninitTimer ( ) ;
CoUninitialize ( ) ;
2006-03-24 06:34:37 +00:00
tfe_shutdown ( ) ;
2008-02-22 21:28:35 +00:00
if ( g_fh )
2006-02-25 20:50:29 +00:00
{
fprintf ( g_fh , " *** Logging ended \n \n " ) ;
fclose ( g_fh ) ;
}
RiffFinishWriteFile ( ) ;
2008-02-22 21:28:35 +00:00
if ( g_hCustomRomF8 ! = INVALID_HANDLE_VALUE )
CloseHandle ( g_hCustomRomF8 ) ;
2006-02-25 20:50:29 +00:00
return 0 ;
}