Archive for the ‘Z80/SMS Emulation’ Category

After having reimplemented most of my C# Z80 emulator in C, I’m now trying to figure out why every ZEXALL test is failing:

james@jameslaptop:~/Projects/Emulation/ZZ80E$ ./a.out z80/zexall_sdsc.sms
Z80 instruction exerciser

ld hl,(nnnn)................. CRC:350e5018 expected:5f972487
ld sp,(nnnn)................. CRC:45f3041a expected:7acea11b
ld (nnnn),hl................. CRC:c9f9ffd8 expected:a3608b47
...etc...

My first guess was that there was a bug in one of the opcodes used to calculate the CRC because I know for sure that the ld opcodes are fine.

However after going through the list of opcodes involved in the CRC with a toothpick, I still can’t find any glaring or even minor mistakes :( The problem with emulator debugging, especially at such an early stage, is that it’s hard to tell if you’re looking in the right place; the bug might be in a seemingly unrelated piece of code, the effects of which have simply cascaded down the chain.

It’s going to be a long night.

Today I have started the momentous task of re-writing my Z80 emulator in C. It would have been possible to simply convert much of the C# code to C, but since I have learnt so much since I started writing it almost a year ago, I have decided to completely overhaul it.

Progress has been remarkably quick, with over a hundred of the most used opcodes implemented so far. One problem with the C# version was that as I wanted a built in disassembler and thought it would be cleaner, I had to have an individual method for each opcode which added the opcode’s mnemonic to the debug output. This time around, I have placed the vast majority of the opcode code in the switch statement, with common parts of code outsourced to inline functions. This has made the code a lot cleaner and manageable. To handle disassembly, I have created a Python script to convert a list of all the Z80 opcodes and their mnemonics to a C function which contains a huge switch statement to return the mnemonic. It might not be the fastest method, but it’s adequate for debugging.

This has been my first experience with C, and so far, it’s been a good one, I love the low level sexiness of it all. Would implementing a C standard library for Master System development using SDCC be too ambitious? :P

Hi all, over the last two days I’ve developed a Silverlight matrix calculator which can add and multiply matrices of arbitrary sizes. I’m not 100% sure it has no bugs, so beware if you’re using it to cheat on your homework! :P

Zoofware Matrix Machine: http://zoofware.com/zoofware-matrix-machine/

It’s the only bit of coding I’ve done over the last few weeks :( However, I haven’t forgotten about the emulator. Once summer is upon us I’ll get cracking, but in the meantime I’m going to work on smaller maths related programs which don’t require as much time or effort to make and supplement my University course nicely. ;)

Having started back at University, I’ve been drowned like a rat in a pile of Maths and haven’t had much time to work on the emulator.

However, I have been advised to build a built in stepping debugger which will make fixing bugs a lot easier (as well as being a less time consuming part of the project), so this will be my main focus for the next couple of weeks. My GUI skills could do with brushing up anyway, so It’ll be a worthwhile development.

I might also try and get a working Silverlight prototype running Sonic 1, just to explore the possible rendering methods (Silverlight doesn’t allow pointers, which will make bitmap manipulation very slow).

Update 12/02/2010: Between having a social life (yeh, I’m not that much of a geek ;) ) and Uni, I’ve literally had no time at all to continue with the project. I can’t see any major work being done until mid-May. Time away from coding though has given me a lot of new ideas for future development.

Following over a week of trying to understand the horizontal and vertical scrolling of the VDP, implementing background priorities and masking, as well as re-writing most of the VDP emulator to be severely cleaner, it is now possible to play Sonic 1 nearly perfectly from start to finish (well up to the 4th zone anyway, then I get bored, I’m not much of a gamer :P ). I suspect there might be a problem with the score counter which wraps after 4 digits, though I’ve not yet had chance to confirm its proper behaviour. There’s also the occasional slowdown, nothing overly serious.

I’ve also managed to track down a bug (I think / hope) which was causing quite a few commercial ROMs and several homebrews to produce garbled background tiles. There seems to be nothing going amiss in the VDP and a common factor of the ROMs with this problem appears to be the use of the RETI and RETN Z80 opcodes. Hopefully this will be fixed up soon.

The next stage of development will be starting work on the sound emulation, as well as possibly coming up with a better GUI.

Update 20/01/10: The Sonic score wrapping was because of a bad flag being set in DAA and is now fixed.

Update 21/01/10: The problem with garbled background tiles with one homebrew game was due to the VDP registers being set to 0 by default. They are now set to FFh. However, similar problems with several commercial games still elude me.

1234

After a lot of bug fixing; I have managed to get ZEXALL passing every opcode bar three (one of which is undocumented). ZEXALL isn’t exhaustive despite it’s own claims, so there’s bound to be many more bugs, but its a step in the right direction.

Sonic now also loads properly, rings can be collected and enemies killed but only to a very limited extent due to horizontal scrolling not being implemented yet.

In the next week or so I’m going to focus on get the VDP working right, along with sprite caching to speed it up a bit (profiling has shown that a huge amount of CPU time is being wasted in VDP.Render() / DrawPattern()).

sonic_vs_zexall

Basic sprites are now working correctly, zexall completes (though of course, with lots of errors ;) which I suspect might be down to a bad halfcarry method). I’ve also implemented rudimentary input.

291209_2291209_1291209

I’ve fixed quite a few little bugs today, implemented the SMS2 memory mapper and ZEXALL is now running quite well (up untill it hits an unimplemented opcode). I believe this marks quite a major milestone as having ZEXALL functioning and reporting any errors will hopefully help to iron out loads more bugs and tighten up the emulation.

Two fingers crossed for having a real SMS game partially working soon!

That’s my coding done until next week. Merry Christmas to anyone sad enough to be reading this :P

231209

Very little progress has been made over the last week or so and it’s doubtful that any thing major will happen until after Christmas.

However, several more homebrew demos are now working correctly, with a fairly decent speed on my 2GHz Core Duo.

As can been seen by the palette test, the VDP emulator is far from complete, the SMS version of ZEXALL is still not working and memory mapping is not implemented yet, simply because of a lack of time along with a personal lack of direction, which I’m working on ;) .

On the positive side; the code for the GUI and VDP has been cleaned up, as well as a little research in replacing the bitmap used to render the graphics with DirectX.

zsmse_37372

Well, after several weeks of hard work, I’ve finally got a real Z80/Master System program running.

The progress made has mainly been with emulating the Master System’s VDP (the TMS9918a), very roughly, there’s still loads to implement. Only one homebrew ROM (not written be me!) is currently working (though I’ve not tested many) but it’s an encouraging milestone non the less.

The next step is to get the SMS VDP version of ZEXALL to run. At the moment, the memory mapper isn’t complete enough for it to get very far.

The speed limiter (usually set to 3.55MHz) has been turned off for the screenshot below. The overall emulation isn’t that efficient at the moment, the bottleneck is mainly in the VDP emulation. However, premature optimization is the root of all evil. Once everything is working more correctly, it can be made faster.

zsmse-vdpprogress