Page 2 of 2

Re: Indy and indigo2 emulation in MESS (WIP)

Posted: Thu Feb 08, 2018 1:44 pm
by OzOnE2k18
Hi, all,

I think this is my first post on here, because I may have had a very old account from around 2005, but I've forgotten the logic details.

I owned an O2 and Octane for a few years back then, but have just recently got the urge to buy another SGI machine.

OK, where do I start? lol

It's probably best just to mention my current / previous projects involving MIPS-based stuff, and then explain what I'm up to now.

It is going to be quite a big first message, but I do tend to type a lot anyway, so please bear with me...

A few months ago, I started an effort to implement the Playstation 1 in an FPGA.
I got it as far as booting the PS1 BIOS to the point of sending the serial debug messages, and actually starting to write some commands to the GPU.

I also hooked up the DE1 dev board to a real PS1 motherboard, so I could then either let the original R3000 run, then monitor what is being sent to the real GPU, or let the CPU core (aoR3000) on the FPGA run instead, then start trying to duplicate the functions of the original CPU.

Many years before, I also started a very long-term project to try to implement the N64 on an FPGA. I designed an adapter PCB to allow a real R4300 CPU to be plugged into the dev board...

It will obviously take me a LONG time to get either of those booting any actual games, but it's a fun learning experience either way.

After that, I designed my own PCB that uses the original R4300, RCP, and RDRAM from the Nintendo 64, but adds HDMI, FPGA, and SDRAM (for eventual cart "emulation")...

The board is booting already, but I'm still working on getting the line doubler working with the HDMI output.
The PCB also needs some more refining around the RDRAM traces, because it currently only boots at 4/5 the usual speed.

Then, about two weeks ago, I thought I'd try to see how far I could boot the SGI Indy BIOS on the same aoR3000 core (as used in the PS1 experiments).

The aoR3000 core does have TLB and cache, but doesn't have an FPU, so it obviously won't boot the Indy BIOS too far without plugging in the R4300.

(which I have done, but not yet hooked it up to the rest of the Indy stuff in the FPGA.)

I wrote a state machine for the R4300 the other day, so I can at least interface to it easily from the FPGA side...

In the mean time, I bought an Octane R10000 CPU module on eBay, because it was only £13 shipped, and I thought it would be "fun" to reverse the pinouts of it. lol

I have this crazy notion of hooking up the R10K to the (larger) dev board, just to see what I can get it to boot.
It's obviously quite a bit more complex than the R3K / R4K stuff though, not to mention having the full 64-bit wide SysAD bus, secondary cache, extra parity checking etc.

But, yesterday I did manage to reverse almost the full pinout for the Octane CPU slot connector using just the R10K datasheet, a cheap VC97 multimeter...

(and, erm, a bit of foil. :p )

So, I'm basically hoping to get further with these projects, but right now, I'd love to implement more of the Indy stuff, and get some graphics output from it.

I'm not quite so great when it comes to C / C++, but know enough to understand the basics of how the MAME driver code works etc.

I've been using the Indy "Bible" PDFs from that wiki page that @dexter1 posted.
Just figuring out how the MEMCFG registers worked took me about two days.

But, that was mainly due to the fact that the wording in MC.PDF wasn't altogether clear, and I also didn't realise that the Indy basically only uses two of the four possible SIMM banks, so that confused the hell out of me for a while. lol

Plus, the "size" values for those registers only pertain to EACH SIMM module, and they are always fitted in groups of FOUR, so I didn't quite get how the memory mapping worked at first.

That resulted in some rather amusing comments in my Verilog...

// The "BASE" bits are compared to bits [29:22] of the requested address.
// That determines where each SIMM is mapped, I think. lol. OzOnE.
// Eg.
// 0x20 = maps the RAM at 0x0800_0000. (usual place for Low Local Memory. Up to 256 MBytes).
// 0x80 = maps the RAM at 0x2000_0000. (usual place for High System Memory. Up to 256 MBytes).
// NOTE: High System Memory only accessed via user virtual address space, kseg0?
// We only have 8 MBytes of SDRAM on the DE1 board, so using eight 1 MByte SIMMS...
wire BNK0 = 1'b0; // 1 subbank (set bit to 0).
wire VLD0 = 1'b1; // Valid (SIMM fitted).
wire [4:0] MSIZE0 = 5'b00000; // 256K x 36 bits, 1 subbanks (1MByte per EACH SIMM, but a group of FOUR SIMMs per bank!)
wire [7:0] BASE0 = 8'h20; // 0x0800_0000. (on each 4 MByte boundary. As there are FOUR, I repeat FOUR 1MB SIMMs per BANK! lol)

wire BNK1 = 1'b0; // 1 subbank (set bit to 0).
wire VLD1 = 1'b1; // Valid (SIMM fitted).
wire [4:0] MSIZE1 = 5'b00000; // 256K x 36 bits, 1 subbanks (1MByte per EACH SIMM, but a group of FOUR SIMMs per bank!)
wire [7:0] BASE1 = 8'h21; // 0x0840_0000. (on each 4 MByte boundary. As there are FOUR, I repeat FOUR 1MB SIMMs per BANK! lol)

// BANKs 2 and 3 don't exist on the Indy!
// Should probably just set the MEMCFG1 register to 0x00000000. OzOnE.
// BUT... Looking at the Indy BIOS disassembly, it appears as though the Indy might set
// both MEMCFG registers to the same value, since it only has the first two banks of SIMM slots??
wire BNK2 = 1'b0; // n/a
wire VLD2 = 1'b0; // Valid bit cleared (no SIMMs fitted!)
wire [4:0] MSIZE2 = 5'b00000; // n/a
wire [7:0] BASE2 = 8'h00; // n/a

wire BNK3 = 1'b0; // n/a
wire VLD3 = 1'b0; // Valid bit cleared (no SIMMs fitted!)
wire [4:0] MSIZE3 = 5'b00000; // n/a
wire [7:0] BASE3 = 8'h00; // n/a

This is what my view of the Indy "output" looks like atm...

I wrote a simple debugger in Verilog, which is the capture you see on the right-hand monitor, and is being generated by the FPGA itself, and output via VGA.

The debugger currently allows me to set a breakpoint (using a PS2 keyboard plugged into the dev board), then I can step through the code using the push buttons.

The serial output is from the Indy BIOS, but clearly it's byte-swapped (32-bit). lol

I still don't know exactly why that is, because the text strings get read from Flash in the same way that the instructions do.
But, I know that the original MIPS CPUs and the MC (Memory Controller) both have options for changing the endianess, so I'll have to figure that out later.

The BIOS is currently passing most of the simpler self-tests now, by spoofing the registers for the SCSI, Ethernet, and NVRAM.
It's still failing on the SDRAM test though, and that's where I'm up to atm.

It looks like the SDRAM controller itself is working fine, it's just an issue with how the Indy BIOS is reading / writing the data, and probably related to the endian issue.

Anywho, I'm definitely interested in helping with any SGI emulation / FPGA efforts if I can, but keep in mind that I don't currently have an SGI machine, so some things are tricky to test. hehe

I've spoken to MarathonMan (author of CEN64) quite a lot via IRC and e-mails in the recent past. Some great work being done for the N64 atm.

Oh, and I just stumbled upon this awesome channel as well, and have been chatting with Mr RTL via Discord.
It looks like he's already implemented a lot of the R4300 in a very short time, and is aiming for a full N64 core...

OzOnE / ElectronAsh.

Re: Indy and indigo2 emulation in MESS (WIP)

Posted: Thu Feb 08, 2018 2:26 pm
by dexter1
Thanks Ozone for joining us here and showing your work in this post.

There is a lot of stuff to cover from your first post. I'll have to reread it a few times, but i have seen the VR4300 layout video which looks very instructive. I am planning on trodding along with qemu to get something emulated, since there is a 64 bit R4000 emulation core available. It will take quite some time to get a basic headless-indy running, though...

Re: Indy and indigo2 emulation in MESS (WIP)

Posted: Thu Feb 08, 2018 2:38 pm
by OzOnE2k18
No problem.

I know I spouted off a lot of stuff for a first post. hehe

I would love to know how to use things like Verilator better, so I can simulate Verilog MUCH faster than having to recompile (resynthesize) for 3-4 minutes.

But, the drawback of that is that it still takes about 5-6 minutes just to render out a few seconds of footage from the video output.

I still can't decide if it would be better to try doing some C simulation stuff first, or just do what I normally do, and keep re-compiling the Verilog for the real dev board, then just see how far I can get on each run.

I never really learned all the C++ extension stuff, so it gets tricky when that is involved.

I much prefer straight C code, even if it looks less organized on first glance.
At least then, you can usually follow what's going on.

It's a bit of a shame when MAME migrated to C++, as I could understand the older code more easily.

Re: Indy and indigo2 emulation in MESS (WIP)

Posted: Thu Feb 08, 2018 11:49 pm
by dexter1
I think you can give C coding the emulator in Qemu a try. Qemu is pure C so you don't need to carry the C++ luggage with you, like what happened in MAME. I have some skeleton stuff derived form the MIPS Magnum.

Qemu has a pure R4000 core and i'm not too familiar with the differences with a VR4300. Probably the CP1 is some kind of vector unit instead of the FPU we commonly know.

Re: Indy and indigo2 emulation in MESS (WIP)

Posted: Wed Feb 14, 2018 4:57 pm
by OzOnE2k18
Not a huge amount of progress to report, other than I got most of the self tests to pass now, and the SDRAM seems to be working.

I made the usual mistake of doing a copy 'n' paste of some older SDRAM controller "code", and it was missing the upper bit of the address.

So, anything that was meant to be getting written to the upper 4MB of RAM was overwriting the first few bytes instead.

But now it just crashes shortly after setting up the TLB and other stuff, so I think this is about as far as it's going to get with the aoR3000 core and the Indy BIOS.

Then I suddenly remembered that I was intending to try the Indigo R3000 BIOS, which in theory should obviously boot further.

It doesn't look like MAME has a driver for the R3K Indigo, sadly, but I might be able to run it's BIOS using the R4400 or R4600 driver, maybe.

I'm now just looking for a copy of the Indigo R3000 BIOS. If anyone has it, please let me know.

I did manage to spoof the DMA registers for the Indy BIOS though, to get it to the point where it crashes just after.

At first, I tried simply forcing the "DMA_RUN" bit HIGH, but that clearly didn't work, as the BIOS then simply waits in an endless loop, until the flag to go Low again. lol

Re: Indy and indigo2 emulation in MESS (WIP)

Posted: Thu Feb 15, 2018 7:10 am
by dexter1
OzOnE2k18 wrote:I'm now just looking for a copy of the Indigo R3000 BIOS. If anyone has it, please let me know.

Have a look here

If you browse around you will find PROM images of the Personal Iris which also has an R3k

Re: Indy and indigo2 emulation in MESS (WIP)

Posted: Sat Feb 17, 2018 3:55 am
by OzOnE2k18
That's awesome, thanks. ;)

I will definitely give that a try later.

Hopefully I will have better luck with booting it further.

Just to see some graphics commands being sent will be a big milestone.

Re: Indy and indigo2 emulation in MESS (WIP)

Posted: Sat Feb 17, 2018 10:53 pm
by OzOnE2k18
OK, I grabbed all of the BIOS files now for the different SGI machines.

It's a really great resource, as I couldn't find anything close to it anywhere else.

I even asked the guys on #n64dev on IRC, as most of them are quite into the SGI stuff too.

I flashed the Indigo R3000 (IP12) ROM to the dev board, and managed to find the serial routine quite quickly.

It's now at the usual point where I need to see which registers it's trying to access for the self test...


EDIT: Probably can't see that image very well on the forum, so here's the direct link...

The other issue now is that many of the hardware registers on the IP12 board are at completely different addresses compared to the Indy, and I haven't yet seen any hardware documents on the IP12 board anywhere. Not on the level of the Indy docs, at least.

But, I'm encouraged to at least see if I can get this past the POST and RAM tests.

The "data path" test really just consists of the code writing a value to some of the hardware regs, reading it back, then writing it to another reg, and so on.

So, to get past those tests, you can usually just add some registers at those addresses, without actually needing to implement anything else.

Or, find the calls to the self-test routines, then just "NOP" them out, which I can do directly in the Verilog, like this...

//(BYTE_ADDR>=32'h1FC0_0560 && BYTE_ADDR<=32'h1FC0_0563) ? 32'h00000000 : // NOP the call to the SDRAM test routine. OzOnE

(BYTE_ADDR>=32'h1FB8_0D13 && BYTE_ADDR<=32'h1FB8_0D17) ? 32'hFFFFFFFF : // ****** FUDGE for Indigo only - spoofs that the serial port is ready ******

//(BYTE_ADDR>=32'h1FC0_12A8 && BYTE_ADDR<=32'h1FC0_12B3) ? 32'h00000000 : // NOP "cache" instructions, as they cause an exception on the aoR3000 atm.

//(BYTE_ADDR>=32'h1FC0_3BF4 && BYTE_ADDR<=32'h1FC0_3BF8) ? 32'h00000000 : // NOP the call to the serial routine. OzOnE

//(BYTE_ADDR>=32'h1FC0_4080 && BYTE_ADDR<=32'h1FC0_4083) ? 32'h00000000 : // NOP the endless loop after a self-test fail. (won't reach DRAM test without this).

Anyway, just thought I'd post a quick update, and to say thanks again for the ROM images. ;)