1 //////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // Nestopia - NES/Famicom emulator written in C++ 4 // 5 // Copyright (C) 2003-2008 Martin Freij 6 // 7 // This file is part of Nestopia. 8 // 9 // Nestopia is free software; you can redistribute it and/or modify 10 // it under the terms of the GNU General Public License as published by 11 // the Free Software Foundation; either version 2 of the License, or 12 // (at your option) any later version. 13 // 14 // Nestopia is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with Nestopia; if not, write to the Free Software 21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 // 23 //////////////////////////////////////////////////////////////////////////////////////// 24 25 #include <new> 26 #include "../NstMachine.hpp" 27 #include "../NstStream.hpp" 28 #include "../NstFds.hpp" 29 #include "NstApiCartridge.hpp" 30 #include "NstApiMachine.hpp" 31 #include "NstApiFds.hpp" 32 33 namespace Nes 34 { 35 namespace Api 36 { 37 #ifdef NST_MSVC_OPTIMIZE 38 #pragma optimize("s", on) 39 #endif 40 41 Fds::DiskCaller Fds::diskCallback; 42 Fds::DriveCaller Fds::driveCallback; 43 File()44 Fds::DiskData::File::File() throw() 45 : 46 id (0), 47 index (0), 48 address (0), 49 type (TYPE_UNKNOWN) 50 { 51 for (uint i=0; i < sizeof(name); ++i) 52 name[i] = '\0'; 53 } 54 DiskData()55 Fds::DiskData::DiskData() throw() 56 { 57 } 58 ~DiskData()59 Fds::DiskData::~DiskData() throw() 60 { 61 } 62 GetDiskData(uint side,DiskData & data) const63 Result Fds::GetDiskData(uint side,DiskData& data) const throw() 64 { 65 if (emulator.Is(Machine::DISK)) 66 return static_cast<Core::Fds*>(emulator.image)->GetDiskData( side, data ); 67 68 return RESULT_ERR_NOT_READY; 69 } 70 IsAnyDiskInserted() const71 bool Fds::IsAnyDiskInserted() const throw() 72 { 73 if (emulator.Is(Machine::DISK)) 74 return static_cast<const Core::Fds*>(emulator.image)->IsAnyDiskInserted(); 75 76 return false; 77 } 78 InsertDisk(uint disk,uint side)79 Result Fds::InsertDisk(uint disk,uint side) throw() 80 { 81 if (emulator.Is(Machine::DISK) && !emulator.tracker.IsLocked()) 82 return emulator.tracker.TryResync( static_cast<Core::Fds*>(emulator.image)->InsertDisk( disk, side ) ); 83 84 return RESULT_ERR_NOT_READY; 85 } 86 ChangeSide()87 Result Fds::ChangeSide() throw() 88 { 89 const int disk = GetCurrentDisk(); 90 91 if (disk != NO_DISK) 92 return InsertDisk( disk, GetCurrentDiskSide() ^ 1 ); 93 94 return RESULT_ERR_NOT_READY; 95 } 96 EjectDisk()97 Result Fds::EjectDisk() throw() 98 { 99 if (emulator.Is(Machine::DISK) && !emulator.tracker.IsLocked()) 100 return emulator.tracker.TryResync( static_cast<Core::Fds*>(emulator.image)->EjectDisk() ); 101 102 return RESULT_ERR_NOT_READY; 103 } 104 SetBIOS(std::istream * const stdStream)105 Result Fds::SetBIOS(std::istream* const stdStream) throw() 106 { 107 if (emulator.Is(Machine::GAME,Machine::ON)) 108 return RESULT_ERR_NOT_READY; 109 110 try 111 { 112 if (stdStream) 113 { 114 Core::Stream::In stream( stdStream ); 115 116 idword offset; 117 118 Cartridge::NesHeader setup; 119 120 byte header[16]; 121 stream.Read( header ); 122 123 if (NES_FAILED(setup.Import( header, 16 ))) 124 { 125 offset = -16; 126 } 127 else if (setup.prgRom >= Core::SIZE_8K) 128 { 129 offset = (setup.trainer ? 512 : 0) + (setup.prgRom - Core::SIZE_8K); 130 } 131 else 132 { 133 return RESULT_ERR_CORRUPT_FILE; 134 } 135 136 stream.Seek( offset ); 137 } 138 139 Core::Fds::SetBios( stdStream ); 140 } 141 catch (Result result) 142 { 143 return result; 144 } 145 catch (const std::bad_alloc&) 146 { 147 return RESULT_ERR_OUT_OF_MEMORY; 148 } 149 catch (...) 150 { 151 return RESULT_ERR_GENERIC; 152 } 153 154 return RESULT_OK; 155 } 156 GetBIOS(std::ostream & stream) const157 Result Fds::GetBIOS(std::ostream& stream) const throw() 158 { 159 try 160 { 161 return Core::Fds::GetBios( stream ); 162 } 163 catch (Result result) 164 { 165 return result; 166 } 167 catch (const std::bad_alloc&) 168 { 169 return RESULT_ERR_OUT_OF_MEMORY; 170 } 171 catch (...) 172 { 173 return RESULT_ERR_GENERIC; 174 } 175 } 176 HasBIOS() const177 bool Fds::HasBIOS() const throw() 178 { 179 return Core::Fds::HasBios(); 180 } 181 GetNumDisks() const182 uint Fds::GetNumDisks() const throw() 183 { 184 if (emulator.Is(Machine::DISK)) 185 return static_cast<const Core::Fds*>(emulator.image)->NumDisks(); 186 187 return 0; 188 } 189 GetNumSides() const190 uint Fds::GetNumSides() const throw() 191 { 192 if (emulator.Is(Machine::DISK)) 193 return static_cast<const Core::Fds*>(emulator.image)->NumSides(); 194 195 return 0; 196 } 197 GetCurrentDisk() const198 int Fds::GetCurrentDisk() const throw() 199 { 200 if (emulator.Is(Machine::DISK)) 201 return static_cast<const Core::Fds*>(emulator.image)->CurrentDisk(); 202 203 return NO_DISK; 204 } 205 GetCurrentDiskSide() const206 int Fds::GetCurrentDiskSide() const throw() 207 { 208 if (emulator.Is(Machine::DISK)) 209 return static_cast<const Core::Fds*>(emulator.image)->CurrentDiskSide(); 210 211 return NO_DISK; 212 } 213 CanChangeDiskSide() const214 bool Fds::CanChangeDiskSide() const throw() 215 { 216 if (emulator.Is(Machine::DISK)) 217 return static_cast<const Core::Fds*>(emulator.image)->CanChangeDiskSide(); 218 219 return false; 220 } 221 HasHeader() const222 bool Fds::HasHeader() const throw() 223 { 224 return emulator.Is(Machine::DISK) && static_cast<const Core::Fds*>(emulator.image)->HasHeader(); 225 } 226 227 #ifdef NST_MSVC_OPTIMIZE 228 #pragma optimize("", on) 229 #endif 230 } 231 } 232