Showing posts with label emulation. Show all posts
Showing posts with label emulation. Show all posts

Monday, 29 November 2010

GitHub

After re-designing and re-engineering the CPU core I've now separated the 680x0 emulation into it's own project and I'm now using GitHub for hosting:

https://github.com/tonyheadford/m68k

This has taken a while although mostly because I've been too busy with other things to work on this. At one point I went up a blind alley writing code generation scripts in Ruby for a different approach to try and maximise speed (minimizing conditional code in the fetch and execute loop) and to further my Ruby skills, but it turned out to generate just too much code and made it unwieldy for both maintenance and my poor IDE.

It's quite exciting to be at a point where I can get back into the Amiga emulation.

Monday, 24 November 2008

Guru Meditation #00000008.00001968

I've spent a fair bit of time recently cleaning things up and simplifying a couple of the interfaces. The MemoryController I discussed in the last post has been cut down quite considerably and I have direct "debug" access to memory now too.

If you imagine a 68000 CPU wired to some RAM and an Amiga 1.3 Kickstart ROM, then that's about the current state of play with Miggy.

If I let the system "boot", my CPU code no longer ends up wandering randomly through memory after a few thousand cycles, which I take as a major positive. In fact what now happens is that the ROM code detects something is wrong and spits out a Guru Meditation and resets the machine. Pretty cool I think. I had a huge grin as I watched it stitch together the Guru message as I stepped through with the debugger. Shame there is no display code yet to show me the flashing red message.

For those that don't know, a Guru Meditation was the Amiga equivalent of a Windows Blue Screen of Death or a *nix kernel panic and usually resulted in a reboot.

Next on the agenda is to try and work out if the Guru Meditation is caused by a CPU emulation bug or the fact that the rest of the system isn't there, and something I don't yet know about isn't setting something in memory properly.

I suspect a combination of both.

Oh and have a gold star if you knew that the Guru Meditation in the title represents a Privilege Violation exception ;)

Saturday, 25 October 2008

Grinding out a result

A week since the last post, how time flies. I've been adding instruction emulation and some unit tests this week. Both rewarding and a bit tedious at times and I've not had quite as much time as I'd hoped this week so progress has been a bit slow, but it's moving in the right direction.

One of my goals in developing this project, was to give me the chance to play with some of the newer language features of Java. I learnt the Java ropes on versions 1.2 and 1.3 and did my certification back when Sun had just started calling it the "Java2 platform". Work hasn't afforded me any opportunity to explore the additions made in 1.5 and later.

Having a strong C and C++ background I thought I knew an enum when I saw one. How wrong could I be. A Java enum is so much more, and after realising their potential I've incorporated several into this project.

One of the key enums in Miggy is the DataSize enum. This has grown quite a bit since it's inception, as I'm finding it so useful. Here's a code snippet:
public enum DataSize
{
Nibble(0, 2, 0x000f,"", 0x0008, 4), Byte(1, 2, 0x00ff,".b", 0x0080, 8),
Word(2, 2, 0x0000ffff,".w",0x00008000, 16), Long(4, 4, 0xffffffff,".l",0x80000000, 32),
Unsized(0, 0,0,"",0, 0);

private final int readSize;
private final int byteSize;
private final int mask;
private final String ext;
private final int msb;
private final int bitSize;

DataSize(int byteSize, int readSize, int mask, String ext, int msb, int bitSize)
{
this.byteSize = byteSize;
this.readSize = readSize;
this.mask = mask;
this.ext = ext;
this.msb = msb;
this.bitSize = bitSize;
}
What this does is create an enum named DataSize that has the values Nibble, Byte, Word, Long and Unsized. However each of these values also has additional data associated with it, passed into the constructor. To keep it simple I haven't shown the accessor methods as they just return the private member variables.

You can probably tell what these extra data fields are by their names, but I'll run through them quickly:
  • byteSize - number of bytes the value represents
  • readSize - number of bytes read when used as addtional data for instruction decoding
  • mask - bitmask used to extract data of this size
  • ext - the extension used when disassembling instructions of this size
  • msb - Most Significant Bit mask, used when determining if a signed value is positive or negative
  • bitSize - the number of bits used in this data size. The same as byteSize multiplied by 8.
Using this enum has meant that I do not need loads of conditional code when emulating or disassembling instructions. Apart from making the code simpler and easier to read, it also means I'm able to write more generic code that can handle byte, word or long sized operations.

For example when disassembling an ADD instruction, each of the "sized" handlers can call a base class method passing a DataSize enum representing the size the instruction is working on.
From the ADD_b.java class which handles the byte sized ADD instruction:

public final DecodedInstruction disassemble(int address, int opcode)
{
return decode(address, opcode, DataSize.Byte);
}

This gives the ADD base class all the information it requires to decode and disasemble the instruction.