Jump to content

65816 soft CPU computer


Recommended Posts

I have a Nexys 4 DDR (the predecessor to the current Nexys A7) FPGA trainer board. It is nice because it includes a number of IO interfaces:

microSD card connector
10/100 ethernet
USB & uart
12-bit VGA port
PWM audio output
PDM mic
One temperature sensor
2 4-digit seven segment displays
16 switches
4 momentary buttons
18 LEDs (2 tricolor)
4 digital / 1 analog pmod ports (for other extension capability)
internal clock speeds of 450 MHz or better are possible (not that I'm claiming any particular implementation can achieve that, just observing the board itself can)
 
It has 607500 bytes of block RAM and 128 MiB of DDR2 RAM and another 16 MB of cellular RAM according to the specs. 15,850 logic slices (4 6-input LUTs & 8 flip-flops each; 63,400 total LUTs & 126,800 total flip-flops).
 
I really like the idea of the MEGA 65 and will probably buy one when and if it ever becomes available. I appreciate the X16 & X8 trying to do something *new* but that still harkens back to the Commodore 8bit era.
 
When I first got the Nexys 4 DDR, my plan was to try to work on a reimplementation of the C=128, but now that I've seen the MEGA 65 and X16 dev approaches, I like the idea of the "create something new" better. I never have enough hours in the day, but I've been giving it a bit of thought lately: What would be a good "new" computer? Something like unto the X16 that harkens back to the earlier era but doesn't try to achieve 100% compatibility.
 
So I've been thinking about creating a 65816 based FPGA computer with this. At the very least it could population the entire 16 MiB address space from the resources on the board. If bank switching was included, it could allow utilization of all the memory on the board. VGA, audio out, audio in, sdcard, and uart gives it plenty of IO opportunities.
 
I am not an experienced FPGA developer, so I'm not under any delusions that this is something that could be done by one inexperienced person quickly. Just something I'm thinking of for fun.
 
The Nexys A7 is available on Amazon right now for $265, so the hardware is "accessible" (and very flexible; it can be far more than just a single computer). So it's "just" a software problem. Those are loaded words, I know.
 
What would you like to see? What do you think the memory map should look like? How much video RAM should it have? More thoughts coming.
Edited by Scott Robison
Link to comment
Share on other sites

  • Super Administrators
3 hours ago, Scott Robison said:

 

 
What would you like to see? What do you think the memory map should look like? How much video RAM should it have? More thoughts coming.

I actually started working some of those things out, myself, when I built my 65816 virtual computer. (It's far from complete; it was just a proof of concept). 

Short version: my ideas have actually changed significantly since I first played with it, but I'd probably do something like this:

Memory: the 65816 can handle 16MB, but that includes ROM and I/O space. However, you could still set up several banks for ROM and I/O and have plenty of user space left. So let's assume a memory model of at least 1MB and up to 12MB of RAM:

The 65816 uses 64K banks, so I'd set mine up something like this:

Bank 0:
Direct Page, Stack, and OS variables. 
Leave at least 32K free for user's software to allocate DP and Stack pages. 

Banks 1-?: BASIC and other program memory. BASIC RAM would start at 01:0000 and go up to the end of RAM

Banks E0-E8: Display memory. Might as well go crazy.
Banks E9-EF: I/O space with 4 VIAs and 4 6551 UARTs. I'd include a MIDI interface as well, just for giggles. 

Bank FF: BASIC and kernel ROMs. The last page of kernel ROM would be KERNAL compatible, to ease porting assembly language programs and C libraries. 
Banks F0-FE: additional ROM banks that can be populated by the user. Each bank should allow for 64K of ROM, with a pre-defined entry point that would be used by all accessory ROMs. (ie: "Initalize at boot", "Start main program", and "Function 1-Function xx)

For the UARTS, I'm thinking:
COM1,2: DE9 or DB25 RS-232 serial port. 
COM3: Network interface: either WiFi or Ethernet terminal adapter, aka "network modem."
COM4: USB UART for direct connection to a PC. 

And, of course, dual SD card sockets. Because SD is the new floppy.

 

Link to comment
Share on other sites

I like Bank 0 being Direct Page, Stack, and system variables, with just enough ROM at the high end to support the various vectors and springboards to user overridable vectors. Maybe a tiny bit of reserved IO space for switching banks of memory. Maybe even the ability to switch bank 0 (I have a lot of RAM I can make available).

Lots of BASIC / other user memory agreed.

Agreed on the lots of display memory. 640 x 480 x 12 bit is just over 7 banks for a maximum resolution screen, so 8 banks is perfect for a single layer maximum bitmap resolution screen (or multiple tile layers and sprites). 16 bits to support an alpha channel would bump it up to over 9 banks. Maybe  12 banks of video ram. One or more banks for audio. 16 banks combined for audio & video sounds pretty good.

One could write to video memory byte by byte (or word by word), but even clearing a full high res screen at 14 MHz would be about 1/2 second ball park. The faster the CPU can run the better, but I was wondering about a coprocessor to provide accelerated video. Maybe. It's down the road.

Putting all this on a FPGA board with a fixed set of IO limits the ability to plug in a ROM chip, though I'm sure something can be done to simulate user definable ROM.

The board only has a single UART built in, but there are lots of PMODs available to enhance the system. RS232 DB9 PMOD is available. Wired ethernet is built in. USB UART is built in. Extra SD CARD PMOD is available. Extra USB UART is available. USB built in appears to only support a translated PS2 keyboard *or* mouse interface, but extra PS/2 PMODs are available.

Link to comment
Share on other sites

  • Super Administrators

You don't actually need to switch banks using an external chip. The 65816 has a bank register, so setting the various banking registers in the CPU switches banks for you. 

With 64K in bank 0, you have a lot of extra room for things like extra Direct page pages (this is movable, unlike the 6502), and extra stack pages (again, movable). IIRC, I think DP and Stack have to say in the first bank, though, so I'd keep that as free of ROM and I/O as possible. 

The only catch is you do need to put the reset vectors into the end of Bank 0, since the CPU looks at the vectors in 00:FFF0-00:FFFF. This means that you'll need a little bit of ROM there, or to pre-populate the RAM during system initialization. For simplicity's sake, I'd probably just populate the last page on bank 0 with ROM. 

IIRC, what Stefany did with the Foenix is to actually copy the last page of data from the boot ROM to the top page of bank 0 when the FPGA started up. This would mean not needing any bank switching circuitry in page 0, which keeps your memory management unit very clean. 

15 minutes ago, Scott Robison said:

Putting all this on a FPGA board with a fixed set of IO limits the ability to plug in a ROM chip, though I'm sure something can be done to simulate user definable ROM.

You just need enough bootstrap ROM to read from storage, and then you can make your "ROMs" just another program file on disk. I'm assuming the FPGA code can be used to pre-populate the RAM, so that should be enough to get a bootstrap loaded into bank 0 (including that reset vector) which would then load the main ROMs in to banks F0 and up.

Once your main ROM banks are loaded, you'd start the CPU, which reads the reset vector and trampolines through a far jump at 00:00F0. That jumps to your kernel ROM, which starts your main system startup. 

 

 

 

Link to comment
Share on other sites

23 minutes ago, Scott Robison said:

Right, I'm just trying to think of what to do with 128 MiB of DDR RAM, and making the 16 MiB address space access even more seems like the thing to do on this FPGA board. Mainly just spitballing ideas.

Setting aside a bank that gets the top (11?) address bits from a window register would give a nice extended RAM window into the DDR RAM. Two banks with two window registers might be even better.

Link to comment
Share on other sites

1 minute ago, BruceMcF said:

Setting aside a bank that gets the top (11?) address bits from a window register would give a nice extended RAM window into the DDR RAM. Two banks with two window registers might be even better.

Agreed on at least two banks to make manipulation easier. Of course, I guess another option would be to treat extra RAM as a bigger REU / RAM disks.

Link to comment
Share on other sites

1 minute ago, Scott Robison said:

Agreed on at least two banks to make manipulation easier. Of course, I guess another option would be to treat extra RAM as a bigger REU / RAM disks.

I expect RAM disks is how I'd treat the banks ... whatever the sector size, [sect1],Y and [sect2],Y ... place the current sector base in the window in the lower two bytes of [sect1],Y and the window page bank in the top byte, Y holds the offset.

Link to comment
Share on other sites

  • Super Administrators
19 hours ago, Scott Robison said:

Agreed on at least two banks to make manipulation easier. Of course, I guess another option would be to treat extra RAM as a bigger REU / RAM disks.

A RAM disk seems like a good way to go... or a "sliding window" REU. 

Actually, what I'd probably do is build a sliding window REU and layer a RAM disk on top of that in software. If someone wanted to use it for RAM disk purposes, they could run a command to partition, format, and pre-load files the RAM disk. For those applications that just need tons of storage space, it could be accessed via a 64K sliding window. 

 

Link to comment
Share on other sites

2 hours ago, TomXP411 said:

A RAM disk seems like a good way to go... or a "sliding window" REU. 

Actually, what I'd probably do is build a sliding window REU and layer a RAM disk on top of that in software. If someone wanted to use it for RAM disk purposes, they could run a command to partition, format, and pre-load files the RAM disk. For those applications that just need tons of storage space, it could be accessed via a 64K sliding window.

For arbitrary sized records of a size that are convenient to work with on a 65816, much of the benefit of a sliding window might be available with most of the simplicity of direct extension of the main address with a pair of 32K windows per bank, so the base of the window register is at A15 rather than A16. Two banks like that and you'd be set for data structured into RAMdisk sectors from 128B to 64KB and source and destination for vectors of arbitrary sized records up to 32KB per record.

Link to comment
Share on other sites

You may want to monkey around with with the 65816 softcore itself.

The MISTer FPGA project has included support for the Nintendo SA-1, which includes things like hardware multiply and divide, an extra full-duplex 16-bit data bus, demultiplexed address pins for the main address bus, and an extra 18-bit address bus.

Then again, it may not be in an HDL you have synthesis tools for, it may use up too much of the FPGA fabric for your plans, and it may require more I/O pins than you can spare.  In which case I've stuck my foot in my mouth, so to speak...

Link to comment
Share on other sites

7 minutes ago, Kalvan said:

You may want to monkey around with with the 65816 softcore itself.

The MISTer FPGA project has included support for the Nintendo SA-1, which includes things like hardware multiply and divide, an extra full-duplex 16-bit data bus, demultiplexed address pins for the main address bus, and an extra 18-bit address bus.

Then again, it may not be in an HDL you have synthesis tools for, it may use up too much of the FPGA fabric for your plans, and it may require more I/O pins than you can spare.  In which case I've stuck my foot in my mouth, so to speak...

That is exactly my plan, actually. I want to glue some existing cores together (the FPGA equivalent of all off the shelf parts) and see what I can come up with. I still want to see a C=128 and figure the MiSTer project is the way to get started on that as well. Vivado in theory supports VHDL and Verilog so hopefully it'll just work (with appropriate changes to handle IO pin definitions that will vary between the Nexys 4 DDR and the DE10 that the MiSTer uses).

As for number of IO pins, the great thing about this is that in trying to create a new computer this way there is no expectation of a particular bit of IO.

Edited by Scott Robison
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

Please review our Terms of Use