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.

Sunday, 6 December 2009

Building the core

I've completed the CPU code re-engineering and I'm currently putting together a disassembler so that I can debug the new CPU. Once I've got this together I'll build a simple monitor/debugger and start running some tests to ensure the CPU instructions all function as they should. It's all rather monotonous at the moment so I'll spare you the details, but I just wanted to let you know that work is continuing, there's just not a lot to show at the moment.

Friday, 6 November 2009

Breakout

I am really enjoying getting back into the code. I've decided to bring all of the individual operation classes into the CPU class and make them inner classes. Lots of reasons for this but to me it just seems to be more logical for the individual instruction methods to access the internals of the CPU directly rather than through some static reference and public methods. This also means I'm removing tons of classes that helped with the previous abstraction and have adopted some simpler ways of decoding opcodes etc.

What this will lead to I hope is a much smaller and cleaner code base with no unnecessary coupling and a nice clean interface. With a bit of luck the performance might be better too, but I'm not really worried about that at the moment.
I am now thinking of creating a new project for the 68k CPU and hosting it on google code or github with a monitor/debugger/disassembler (and perhaps an assembler too) but separate from the Miggy project.

Once this is done I'll then return to Miggy and build it using this CPU core.
Thoughts anyone ?

Sunday, 1 November 2009

Back in the saddle

Woooah where did 2009 go ?

I've recently been having huge urges to get back on with this little project and I decided to go grab the code again and begin trying to find time to do some more.
Amazing how a little time makes you look at things differently. I've only just started nosing through the code again and plenty of "what was I thinking!" thoughts are appearing.
I've decided to switch to Eclipse to continue developing Miggy. I've switched full-time to my MacBook Pro now and my beloved IntelliJ isn't behaving itself properly on Snow Leopard. I can't afford or justify the upgrade to the latest version when there's free tools around that should be up to the job. I say "should be" because my previous attempts at using Eclipse have ended in plenty of swearing and its swift removal from my hard-drive. But that was a long time ago and I'm a forgiving soul/sucker for punishment.

My first thoughts are I should really get the core 68k emulation done and dusted as a separate module. I think it's there or there abouts already but I've found loads of dependencies and coupling that really shouldn't be in there, so I want to clean it up. This will certainly help me get back in the saddle with the code too.

Saturday, 17 January 2009

Progress or Procrastination

I've just commited a huge update into the code repository.  Still little display code progress but an awful lot of refactoring has gone on.

I've extracted the interfaces, enumerations and exceptions out into an "api" package and changed the system model loader to load all of the main classes dynamically based on a configuration file. The aim is to enable different implementations of key components if or where necessary.  For example this would enable different rendering engines/technologies to be used to handle the display or special cases for components that need tweaking for particular applications.

I've also added a rudimentary console so that the machine can be controlled from the command line interactively.   This will be fleshed out as I progress.  The graphical debugger is still there although not accessible at the moment, so eventually a user can choose between command line operation or a graphical front end (or a bit of both).

My main focus next will be trying to get something displayed.  This must be the second or third time I've said that, but I found the refactoring had to come first to make way for modular display code.

I'd also like to create a sub project for the disassembler.  The original release in the code Google Code Site is well out of date now and was based on the state of the emulator project at the time.  So I have no way of building this separately, and I'd like to update it at some point.

Tuesday, 23 December 2008

Coughs and Sneezes

What with festive season preparations and parties followed by a nasty dose of flu, there hasn't been much progress in the last couple of weeks, so not much to report.

I'm starting to feel normal again now, apart from a wretched cough,  and the will to spend time coding in the evenings is returning.  I'm hoping to get chance to implement the display code over the Christmas holidays.  I'm really looking forward to seeing the kickstart screen with the blue disk held in a hand appear.

Have a Merry Christmas !

Wednesday, 10 December 2008

Gotcha - fun with the debugger

It's been bugging me why the emulator loops and RESETs while running the Kickstart 1.3 ROM, so I thought I'd try and trace through it a bit more and see if I could get to the bottom of it.

The issue manifests itself as a privilege violation exception - a privileged instruction was executed without the supervisor bit being set in the status register.

I had left it alone for a while because I thought that it's probably caused by the lack of the rest of the hardware and that one of the as yet unemulated chips would trigger an interrupt or populate some internal structure that would prevent the problem.

I had been starting to look at handling interrupts generated by the hardware accessed through the INTREQ and INTENA registers.  How these are set and cleared was key to finding one of the problems.

The first thing I took a deeper look at was a series of write/read/compare instructions on a reserved memory area.  Actually this was the area of memory reserved for the trapdoor expansion RAM (which wasn't configured in my current configuration).  Initially I thought it was just a test to see if a value written to the area could be read back again, but the values and the addresses the ROM code used were different.  Puzzled as to why it would expect a specific value back from a particular address when writing a different value to a different address, in what I thought was unmapped memory space, got me thinking.  I looked at the instructions again:

move.w #$3FFF, -$F66(a2)
tst.w -$FE4(a2)
bne ....
move.w #$BFFF, -$F66(a2)
cmp.w #$3FFF, -$FE4(a2)
beq ....

It looked like the set/clear behaviour of the interrupt registers (and a few other control registers).  Certain control registers allow the setting and clearing of bits by having a "switch" bit.  When a value is written to the register with the switch bit set,  the register will set all of its bits that correspond to the set bits in the value, ignoring any cleared bits.   When a value is written with the switch bit cleared, the register clears all of it's bits that correspond to a set bit in the value, again ignoring the unset bits.

I knew the a2 register was set to the address $C40000 so I decided to look and see what the -$F66 and -$FE4 offsets would give me.

$C3F09A and $C3F01C

These meant nothing to me except that I thought the low word of the addresses looked familiar.  In fact if was the same as a pair of registers I'd been using when looking at the interrupts.
The write-only INTENA and read-only INTENAR registers are at the addresses $DFF09A and $DFF01C.  Could it be that the custom registers were mapped into this address space ?

After a hunt on the net and a browse through the source code of the excellent WinUAE emulator it appeared that it was indeed mapped several times through the memory area between $C00000 and $E00000.

To map the area through these ranges I added an additional class named CustomChipMirror and added it to the memory map of the MemoryManager.  This class modifies the address of the any memory access requests and redirects them to the CustomChipController.

It worked, but it didn't stop the RESET problem.  The ROM code still got there eventually.

I carried on tracing through the ROM code and I then noticed that my ADDQ code wasn't working correctly.  ADDQ allows you to add a value between 1 and 8.  It's a short 16-bit instruction using 3 bits to hold the value.  When the value is zero it represents the value 8.  Or at least it should, my code had forgotten this fact.
Another bug fixed.

The RESET loop was still happening.

I kept going and got to the point where the exception was actually occuring.  First the supervisor bit was cleared from the status register, meaning the CPU drops back into user mode.  Shortly after this a call is made to the Supervisor() function in the Exec ROM library and the supervisor bit is set again in the status register.  This causes a privilege violation exception as we're in user mode now, and the code jumps to the exception handler installed by the ROM.

The exception handling code examines the address put on the stack when the exception occurred and branches if it matches a specific value.  Looking at it I could see that the address on my stack was 4 bytes different to the one it was looking for.  The ROM was loooking for $FC08E6 and I had $FC08EA.  I went and checked my exception code.  It all looked good, swap stacks, push the PC and SR onto the stack, set the supervisor bit and set the PC to the exception handling address.

I re-read the exception handling section in my 68000 programming book and this caught my eye:

"The current values of the PC (which normally points to the the next instruction to be executed) and the status register are pushed onto the supervisor-mode stack".

Hang on a minute ... "normally" ?
A bit of digging around revealed that the instructions that change the supervisior mode of the status register, fetch the instruction words in supervisor mode, meaning that if a privilege violation exception occurs the PC points to that operation not the next one to be executed.
I added a new raiseSRException() method to the CPU class and called that when raising exceptions from ORI/ANDI/EORI and MOVE when SR was the destination.

And the ROM no longer RESETs !
Result.