看板 Emulator 關於我們 聯絡資訊
只是消息更新,還沒有下載: http://melonds.kuribo64.net/ melonDS is a new emulator project. My goals for it are to do things right and fast. Time will tell how far we can get in that direction. If you know me, I'm not new in the emulation scene. I'm responsible for lolSNES/blargSNES, among others. I'm not new in the DS scene either, I worked a lot on DeSmuME back in the days. Why I'm straying away from DeSmuME is not something I will get into here. So here I am, writing my own emulator for the second time. The hardest part in starting an emulator project from zero is managing to build something that resembles an emulator. It takes a fair amount of work before you can start getting results. To this day, melonDS has gotten over the initial stage and does give some results. Nothing actually works aside from the very simple ARMWrestler CPU test, but hey, it's a start. melonDS has a 'good enough' subset of the ARM instruction set implemented, as well as a few hardware features, so getting things to run is mostly a matter of implementing the rest of the DS hardware. One thing I want to do is being able to boot from the BIOS, like an actual DS. I was unable to get it to work in DeSmuME back then, but manually loading a DS firmware and booting it (thus skipping the BIOS) did work. The progress of melonDS in regard to this is encouraging. The BIOS loads the firmware into memory and boots it. The firmware gets to the point where it tries to use the IPC FIFO, which I haven't implemented yet. Interesting things ahead! Of course, melonDS will later have the option to boot a game directly, like all the emulators out there do. But for the sake of accuracy, I want to be able to boot from the BIOS. The holy grail would be wifi emulation, especially local multiplayer, which I could never get working in DeSmuME. Time will tell if that goal is achievable. -- Even if still very far. After a while, melonDS finally boots commercial games. Among my small game library, the compatibility rate is encouraging, even. Here are a few screenshots, for example: http://melonds.kuribo64.net/img/melonshowoff1.png
http://melonds.kuribo64.net/img/melonshowoff2.png
http://melonds.kuribo64.net/img/melonshowoff3.png
http://melonds.kuribo64.net/img/melonshowoff4.png
Getting there took a while of implementing new features, but also bashing my head against obscure bugs that often turn out to come from silly little things. As an example, a bug that prevented games from booting. On ARMv4/v5, the LDR opcode has the particularity that if you read from an address that isn't word-aligned, it aligns the address, and rotates the word it read so that the LSB is the byte pointed by the original address. In melonDS, it was implemented the following way: u32 val = ROR(cpu->DataRead32(offset), ((offset&0x3)<<3)); At first glance, looks alright, doesn't it? Except ROR() is a macro, defined as follows: #define ROR(x, n) (((x) >> (n)) | ((x) << (32-(n)))) This basically ends up calling cpu->DataRead32() twice. This isn't a big deal when reading from RAM, it only wastes some CPU time, but the bug goes unnoticed. However, it has nasty side-effects when reading from I/O registers like the IPC FIFO. Next up, aside from GPU-related work, were features like touchscreen or save memory. Touchscreen emulation isn't too hard. Saves are a little more involved. In itself, it's nothing big, the save memory is an EEPROM or Flash chip accessed over a dedicated SPI bus. The issue is how to determine the correct memory type. The ROM header doesn't contain that information, so we must guess it. The current implementation waits for the game to start writing to the save memory and tries to determine the memory type from the length of the longest write. The idea is to guess the memory page size, from which the memory type and size can be inferred. If a save file is already present, those variables are inferred from the file's size. With that covered, games can do something more interesting than sitting on a "failed to erase data" screen. So far, this is what I have tested: New Super Mario Bros: non-3D minigames playable, freezes when going ingame Super Mario 64 DS, Rayman Raving Rabbids 2, Meteos demo: "playable", but no 3D graphics Mario Slam Basketball, Rayman DS: get stuck trying to do a GX FIFO DMA Mario & Sonic at the Olympic Games, Mario Kart DS: freeze when trying to display 3D graphics Super Princess Peach: playable, 3D effects missing Worms 2 Open Warfare: seems to work, but menus invisible -- this game is all 3D It appears that there are now two main immediate directions for melonDS: UI and 3D support. The UI part will need some thinking to pick the best framework. The current UI is something I quickly threw together using the Win32 APIs so I could see graphics, but for the "final" product, I want something cross-platform. An idea is to provide a quick SDL-based interface and a more complete Qt interface. I don't like some aspects of Qt, but regardless, it's a possible candidate, and a powerful one. A decent UI would also support things like selecting a ROM file instead of hardcoding the filename, choosing a save memory type should autodetection fail, choosing whether to boot from the BIOS or from the game directly, all those things. 3D support is going to be required to get further into emulating games at this point. Past the obvious reason that they can be unplayable without 3D graphics, some require the hardware support to get further. The 3D GPU has a FIFO for sending commands to it, called GX FIFO. It can be set to trigger an IRQ when it gets empty or less than half-full. Some games wait for the IRQ before sending more commands, some others use DMA to send their command lists automatically. Without proper support, these games would just hang. The most bizarre game is probably Super Mario 64 DS. It does enable the GX FIFO IRQ at times, but never waits for it -- instead polling the GXSTAT register with the following code: 0205A390 LDR R12, =0x4000600 0205A394 LDR R4, [R12] 0205A398 AND R4, R4, #0x7000000 0205A39C MOV R4, R4, LSR#24 0205A3A0 ANDS R4, R4, #2 0205A3A4 BEQ #0x0205A394 This is basically an inefficient way of checking whether bit 25 of GXSTAT (0x04000600) is set. ((GXSTAT & 0x0700000) >> 24) & 0x2 Could have as well been: GXSTAT & 0x02000000 Why it doesn't just wait for the GX FIFO IRQ is a mystery (waiting for an IRQ lets the CPU go idle and saves power, unlike this kind of busy loop). Stay tuned for more reports of the melonDS adventure! -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 101.13.146.176 ※ 文章網址: https://www.ptt.cc/bbs/Emulator/M.1486433805.A.634.html ※ 編輯: protect6090 (101.13.146.176), 02/07/2017 10:18:44
snes9xw: wow~ 02/07 11:32