⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 how2port.txt

📁 著名SFC模拟器Snes9x的源代码。
💻 TXT
📖 第 1 页 / 共 3 页
字号:
                   How to Port Snes9x to a New Platform                   ====================================Version: 1.01Date: 23-December-1998(c) Copyright 1998 Gary Henderson (gary@daniver.demon.co.uk)Introduction============This is brief description of the steps involved in porting Snes9x, the SuperNintendo Entertainment System emulator, to new hardware which is at leastsimilar to Workstation or PC. It describes what code you have to write andwhat functions exist that you can make use of. It also gives some insights asto how Snes9x actually works, although that will be subject of anotherdocument yet to be written.Host System Requirements========================A C++ compiler, so you can compile the emulator! Snes9x really isn't writtenin C++, it just uses the C++ compiler as a 'better C' compiler to get inlinefunctions and so on. With some modification, it could be converted to becompiled with an ordinary C compiler. Snes9x isn't very C type safe andwill probably not work on a system who's integers are less than 32-bits widewithout lots of editing.If the host system uses a CPU that implements the i386 instruction set thenyou will also want to use the three assembler CPU cores, although I recentlyscrapped the SPC700 assembler code (too many bugs) and replaced it withcompiler generated assembler code that I haven't got around to optimisingyet.  The 65c816 and SPC700 code needs to be assembled using the GNUassembler that comes with gcc and the Super FX code assembled with NASMv0.97 or higher. gcc is available from lots of sites. NASM is available fromhttp://www.cryogen.com/NasmA fast CPU. SNES emulation is very compute intensive: two, or sometimes threeCPUs to emulate, an 8-channel 16-bit stereo sound digital signal processorwith real-time sample decompression, filter and echo effects, two customgraphics processor chips that can produce transparency, scaling, rotationand window effects in 32768 colors, and finally hardware DMA all take theirtoll on the host CPU.Lots of RAM. The SNES itself has 128k work RAM, 64k V-RAM and 64k sound CPURAM. If a Super FX game is being emulated, that usually comes with another64k inside the game pack. Snes9x itself needs 4Mb to load SNES ROM imagesinto (or 6Mb if I ever figure out the SNES memory map of the 48Mbit ROMimages out there), 256k to cache decompressed sound samples in, 512k tocache converted SNES tiles in, and another 64k for S-RAM emulation. Andthat's not counting a few large lookup tables that the graphics code needsfor speeding up transparency effects plus few other tables used by the ZSNESSuper FX code. It all adds up to 7Mb (ish). Add to that RAM needed tostore the actual emulator code and RAM required by the host operating systemand any other process that is running; that's lots of RAM. Well, it is ifyour host system only has a few mega-bytes of RAM available.An 8-bit, 256 color (one byte per pixel) or deeper display, at least 256x239pixels in resolution, or 512x478 if you're going to support the SNES'hi-res. background screen modes. Ideally, a 16-bit, 65536 color screen modeis required if you want to support transparency at speed, as that is what thecode renders internally. Any other format screen, with transparency enabled,will require picture format conversion before you can place the renderedSNES image on to the screen.Sound output requires spooling 8-bit or 16-bit, mono or stereo digital sounddata to the host computer's sound hardware. The DOS port uses interruptsfrom the sound card to know when more sound data is required, most otherports have to periodically poll the host sound hardware to see if more datais required; if it is then the SNES sound mixing code provided by Snes9x iscalled to fill an area of system memory with ready mixed SNES sound data,which then can be passed on to the host sound hardware. Sound data isgenerated as an array of bytes (uint8) for 8-bit sound or shorts (int16) for16-bit data.  Stereo sound data generates twice as many samples, with eachchannel's samples interleaved, first left's then right's.For the user to be able to control and play SNES games, some form of inputdevice is required, a joystick or keyboard, for example. The real SNES canhave 2 eight-button digital joy-pads connected to it or 5 joy-pads when anoptional multi-player adaptor was purchased, although most games only requirea single joy-pad. Access to all eight buttons and the direction pad, ofcourse, are usually required by most games. Snes9x does emulate themulti-player adaptor hardware, if you were wondering, but its still up toyou to provide the emulation of the individual joy-pads.The SNES also had a mouse and light gun available as optional extras,Snes9x can emulate both of these using some form of pointing device,usually the host system's mouse.If an accurate, constant SNES play rate is required, then a real-time timerwill be needed that can time intervals of 16.7ms (NTSC frame time) or 20ms(PAL frame time).Some SNES game packs contained a small amount of extra RAM and a battery soROMs could save a player's progress through a game for games that takes manyhours to play from start to finish.  Snes9x simulates this S-RAM by savingthe contents of the area of memory normally occupied by the S-RAM into filethen automatically restoring it again the next time the user plays the samegame. If the hardware you're porting to doesn't have a hard disk availablethen you could be in trouble.Snes9x also implements freeze-game files which can record the state of theSNES hardware and RAM at a particular point in time and can restore it tothat exact state at a later date - the result is that users can save a gameat any point, not just at save-game or password points provided by theoriginal game coders. Each freeze file is over 400k in size. To help savedisk space, Snes9x can be compiled with zlib, which is used to compress thefreeze files, reducing the size to typically below 100k.  Download zlib fromits homepage at http://www.cdrom.com/pub/infozip/zlib/, compile Snes9x withZLIB defined and link with zlib. zlib is also used to load any compressedROM images Snes9x my encounter, compressed with gzip or compress.Porting=======In theory you will only need to edit port.h, then in a separate file writeall the initialisation code and interface routines that Snes9x expects theyou to implement. You, no doubt, will discover otherwise....There are several compile-time only options available:DEBUGGER--------Enables extra code to assist me in debugging SNES ROMs. The debugger has onlyever been a quick-hack by me and user-interface to debugger facilities isvirtually non-existent. Most of the debugger information is output viastdout and enabling the compile-time options slows the whole emulator downslightly. However, the debugger options available are very powerful; youcould use it to help get your port working. You probably still want to shipthe finished version with the debugger disabled, it will only confusenon-technical users.VAR_CYCLES----------I recommend you define this. The main CPU in the SNES actually varies inspeed depending on what area of memory its accessing and the ROM accessspeed of the game pack; defining VAR_CYCLES causes Snes9x to emulate this,using a good approximation, rather than fixed cycle length as ZSNES does. Theresultant code is slightly slower. Leaving it undefined results in many moreemulation timing errors appearing while playing games.CPU_SHUTDOWN and SPC700_SHUTDOWN--------------------------------Again I recommend defining both of these. They are both speed up hacks.When defined, Snes9x starts watching for when either the main or sound CPUsare in simply loops waiting for a known event to happen - like the end ofthe current scan-line, and interrupt or a sound timer to reach a particularvalue. If Snes9x spots either CPU in such a loop it uses its insiderknowledge to simply skip the emulation of that CPU's instructions until theevent happens. It can be a big win with lots of SNES games.I'm constantly amazed at the ingenuity of some programmers who are able toproduce complex code to do simple things: some ROM's wait loops are socomplex Snes9x fails to spot the CPU is in such a loop and the shutdownspeed up hacks don't work.You might be wondering why VAR_CYCLES, and the two SHUTDOWN options have tobe enabled with defines, well, in the past they sometimes introducedproblems with some ROMs, so I kept them as options. I think I've fixed allthe problems now, but you never know...SPC700_C--------Define this if you are using the C/C++ version of the SPC700 CPU core. Itenables a ROM compatibility feature that executes SPC700 instructions duringSNES DMA, it allows several games to start that would otherwise lock up andfixes music pauses when ROMs do lots of DMA, usually when switching betweengame screens.ZLIB----Define this if you have the zlib library available and you want it tocompress freeze-game files to save disk space. The library is also used tosupport compressed ROM images.NO_INLINE_SET_GET-----------------Define this to stop several of the memory access routines from beingdefined in-line. Whether the C++ compiler actually in-lines when this symbolis not defined is up to the compiler itself. In-lines functions can speed upthe C++ CPU emulations on some architectures at the cost of increased codesize. Try fiddling with this option once you've got port working to see ifit helps the speed of your port.EXECUTE_SUPERFX_PER_LINE and ZSNES_FX-------------------------------------Define these if you're going to be using the ZSNES Super FX i386 assemblercode, otherwise leave them both undefined. In theory,EXECUTE_SUPERFX_PER_LINE can also be defined when using the C++ Super FXemulation code, but the code is still buggy and enabling the optionintroduces more problems than it fixes. Any takers for fixing the C++ code?JOYSTICK_SUPPORT, SIDEWINDER_SUPPORT and GRIP_SUPPORT-----------------------------------------------------These options enable support for various input devices in the UNIX and MS-DOSport code. They're only of interest if you're able to use the existing UNIXor MS-DOS port specific code.port.h======If the byte ordering of the target system is least significant byte first,make sure LSB_FIRST is defined in this header, otherwise, make sure its notdefined.If you're going to support 16-bit screen rendering (required if you wanttransparency effects) and your system doesn't use RGB 565 - 5 bits for red,6 bits for green and 5 bits for blue - then you'll need make sure RGB555,BGR565 or BGR555 is defined instead. You might want to take a look at the*_LOW_BIT_MASKs, *_HI_BIT_MASKs and BUILD_PIXEL macros to make sure they'recorrect, because I've only every tested the RGB565 version, though the Macport uses the RGB555 option. If your system is 24 or 32-bit only, thendon't define anything; instead write a conversion routine that will take acomplete rendered 16-bit SNES screen in RGB565 format and convert to theformat required to be displayed on your hardware.port.h also typedefs some types, uint8 for an unsigned, 8-bit quantity,uint16 for an unsigned, 16-bit quantity, uint32 for a 32-bit, unsignedquantity and bool8 for a true/false type. Signed versions are alsotypedef'ed.The CHECK_SOUND macro can be defined to invoke some code that polls thehost system's sound hardware to see if it can accept any more sound data.Snes9x makes calls to this macro several times when it is rendering the SNESscreen, during large SNES DMAs and after every emulated CPU instruction.Since this CHECK_SOUND macro is invoked often, the code should only take avery small amount of time to execute or it will slow down the emulator'sperformance. The Linux and UNIX ports use a system timer and set a variablewhen it has expired; the CHECK_SOUND only has to check to see if thevariable is set. On the MS-DOS and Mac ports, the sound hardware is notpolled at all, instead it is driven by interrupts or callbacks and theCHECK_SOUND macro is defined to be empty.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -