S100 banner
Home S-100 Boards History New Boards Software Boards For Sale
Forum Other Web Sites News Index    

The S-100 Bus FPGA 80286 SBC Board.
   Final Board

The original S100 bus FPGA board, "V2" FPGA Prototype board and FPGA Z80 SBC have proven to be a very useful development boards.  The boards can be morphed into many functions.  If you are not familiar with these boards it is essential you read up on the FPGA_Z80_SBC board before going any further here.  Much of what is written here assumes you are familiar with those boards.  There are also  introductions to FPGAs and how to program and use them.

We will now (again), move things up a notch and use the full power of the Cyclone IV FPGA. We will construct and program the FPGA to be a S100 Bus 80286 CPU board.  The board will act as a fully self contained S100 bus "Single Board Computer "(SBC), somewhat similar to our earlier S100 bus Z80 SBC and 80286 CPU board-- but much more powerful.
The board contains:-

A "real' 80286 CPU and 82288 Bus Controller chip set running at 10mHz.
An 80X40 line VGA character terminal with its own ROM character table and 4K graphics RAM
An FPGA internal ROM 64K 16 bit wide ROM containing the 80286 monitor along with diagnostics support for the SD cards.
An IBM PC PS2 keyboard input port (with input converted to standard ASCII)
A USB serial I/O port at speeds up to 38K to a PC
A "real" 8259A interrupt controller for onboard and S100 bus interrupts.
Three SD micro Card slots and an interface to boot MSDOS V4.01
There is an FPGA interface to an onboard SPI DS1305 clock/calendar RTC chip with battery backup.
An onboard buzzer for the console output "Bell" character.
An 4 bit IOBYTE input port and 4 status LEDs.
The board has 1M of onboard 16 bit wide RAM that is addressable locally to the 80286
Onboard CPU Reset switch

While the board internally is quite complex,  externally it looks and behaves very simple. It will be an ideal board for somebody new getting into building an S100 bus system since with this board alone and a simple USB/FPGA programmer they can have a complete MSDOS system. Then gradually the user can inactivate various sections within the FPGA code and activate the corresponding old/new S100 boards they have in their system.   They can start off looking upon the FPGA as a black box.   In fact to get started you don't even need an S100 bus -- just hookup 8V to a jumper on the board and connect the onboard USB port to you PC system to act as a  TTY character terminal.

Keeping in mind the above potential audience, I will try and over-explain some things below.  Our "hard core" audience can just skip ahead.  That said,  this is NOT a board for a complete electronic novice. Minimally you should have some soldering experience and knowledge of electronic circuits.  You should for example be comfortable with web sites that describe Arduino or Raspberry circuits.  You should have a basic understanding what a Field Programmable Gated Array (FPGA) is. If not, look them up on web.  In summary, these chips allow you to lay down any circuit you might come up with within the chip just like you might do by soldering hundreds of TTL/74xxx chips together as in the old days.  Its all done in software. The resulting code/pattern is then programmed into the chip.

For those more electronically sophisticated... I looked at using an internal 8086 or 80286 direct FPGA simulator.  I could not find a free one in the public domain.  There is an nice 80186 FPGA simulator by Jamie Iles but unfortunately the code was too complex/convoluted for me to use.  Also the 80186 has defined I/O ports for its support components that often conflict with other S100 board hardware. 

I also tried to eliminate the use of the 82288 Bus Controller chip.  After fooling around with FPGA simulations for over a week I gave up and just bit the bullet by adding the chip.  Exactly the same thing happened for the 8259A Priority Interrupt Controller.  That one was even more frustrating. Interrupts "almost worked" but over time (hours) would place a false vector on the bus.  Again for high speeds/reliability I just added the chip. The good news is I managed to bring the 82284 Clock Generator into the FPGA.

Finally I would like to point out that while the chip density on the board is not too bad,  the routing to the chip pins is very dense.  It took a number or chip placement try's to get everything on to a 2 layer board. Even with that Freerouter took up to 3 days to get a reasonable solution.

What Is Needed
The FPGA we will use here is an Altera/Intel Cyclone IV FPGA.  This chip is currently in about the middle range of the programming capacity of FPGA's.   The actual chip uses a "Ball Grid Array" method of soldering it to a printed circuit board.  This requires very specialized equipment, so normally one purchases an "adaptor board" for these chips with the chip on it.  Besides providing "normal" pin attachments to (in our case), the main S100 board,  these adaptors contain a number of voltage regulators, Flash RAM, a programming socket  and other components these FPGAs require to operate.

As for our previous boards we will use the WaveShare "CoreEPCE10" Cyclone IV board adaptor. Its schematic can be seen here.
  CoreEP4CE USB Blaster  
The second thing you will need is a device to program the FPGA chip itself. 
There are many FPGA programmers available. I really like the USB Blaster (V2) that Waveshare sells.  Its simple and reliable.  And importantly, works directly within Intel's Quartus V12 (see below). The good news is; with this board you will not need to purchase a separate EEPROM burner, GAL programmer or CPLD programmer.

Somewhat unexpectedly you will need to pay particular attention to the special very tightly spaced pins on the above adaptor board.  Because there are so many FPGA output pins, its not practical to have a connector with the standard PC board 0.1" pin spacing.  The above WaveShare unit uses unusual 2 mm dual row pin connectors.  Unlike to normal 0.1" connectors these are quite rare an expensive.  If you solder these female sockets to the board the WaveShare adaptor sits quite high on the board and will prevent the next S100 bus slot from being used.  If you carefully remove the JTAG socket top border edge with a wire cutter - all around about 1/8", it will fit into most S100 bus motherboards without taking up two slots. Alternatively you can solder the adaptor directly to the S100 board. Of course removing the adaptor is all but impossible in this case. 

Please note the 2 mm dual row pin connectors (Digi-Key #1212-30-ND sockets) for the WaveShare adaptor are quite tricky to fit on to the board.  I found the best way to do this (after trimming them to pin size), is to push them half way on to the adaptor pins and then wiggle them to fit the whole unit on to the S100 board.  Figure on spending 10 minutes on this step!  Do not solder them to the board first and then try and press the adaptor down on them. They are very fragile and internally the leaves will bend if socket angles are not exactly correct.  When in place, check each pin is visible on the back of the board before soldering.  Only then solder all around.  Add as little solder to each pin as possible - the narrow pins have a tendency to wick up solder internally.  Better sockets are the Digi-Key #1212-1786-ND  100 pin sockets (carefully clipped to size).

The rest of the boards components are standard -- available from Jameco, Mouser, Digi-Key etc. For prototype boards I generally use "double swipe" IC sockets. For a critical board like this I prefer to use "Machine Tooled" IC sockets.  However they are more expensive and you have to be particularly careful not to bend the actual IC pins. 

The choice of 80286 CPU and 82288 Bus Controller chips is quite important.  I spent almost a month getting the CPU/Bus Controller/8259A interrupt controller working together reliably at 8-10MHz speeds.  The main problem was the 18.2 pulses/second for the MSDOS timer function would cause a CPU abort/issue a false interrupt vector over time.  In the end I found the choice of CPU and its rated speed was most critical. Best by far are the AMD 12 or 16 MHz 80286 CPU's (e.g. AMD, N80L286-12/s).  The 1985 (or presumably later) Intel 8MHz also seem to work very well at 10Mhz.  In all cases the Bus Controller is the Intel 82288-10 (10 MHz), and the 8259A is the Intel 8259A-2.  We will see that these chips require 4 I/O and INTA wait states (but no RAM wait states at 10MHz). Somewhat contradictory, adding more wait states made the system less reliable. All these chips I obtained from
Unicorn Electronics -- an outfit I highly recommend for things like this. Make sure you order the PLCC versions of the CPU.

Programming the Cyclone IV FPGA
As mentioned above, in order to actually implement a circuit the FPGA must be programmed.  During board development the code is passed to a Flash RAM on our adaptor board from which the FPGA has enough intelligence to load it from there and run.   This means that if we power down the board that code is lost and the chip has to be re-programmed.  As we shall see below, when one is satisfied with the code there is a separate process to burn it into the chip so it is not lost upon power up.  This is a slower process and so is not normally done.  You can however program by both methods essentially an infinite number of times. 

There are two major languages to program FPGA's Verilog and VHDL.

Verilog was created by Prabhu Goal, Phil Moorby, Chi-Lai Huang and Douglas Warmke around 1984. Originally, Verilog was only intended to describe and allow chip hardware simulation. The automated synthesis of subsets of the language to physically realizable gates etc. was developed after the language had achieved widespread usage. Verilog stands for the words "verification" and "logic". There were many upgrades/extensions over the years. The last major version appeared in 2005.

VHDL was originally developed for the U.S Department of Defense in order to document the behavior of the ASIC chips that supplier companies were including in equipment. Because of this background much of the syntax was based on the Ada programming language. The language has undergone numerous revisions and has a variety of sub-standards associated with it that augment or extend it in many ways, the last major release being in 2008.

Usage between the two tends to be polarized. Probably because of its ADA/Pascal style VHDL seems to be more popular in Europe.  The "C'" style syntax Verilog seems to be more popular in the US. 

With both the above languages you can write programs line by line just like is C or Java etc. Alternatively you can use a newer graphic diagram approach which in the background converts your graphic diagrams into Verilog or VHDL code -- totally transparent to the user.  This approach uses  a special file called a
"Block Diagram File" (.bdf) (for Altera/Intel chips). The whole process is somewhat like writing a web site page.  You can either write the whole page yourself in HTML or use something like I'm using here (Expression Web),  to "draw" a web page in blocks, graphics etc.

Again, usage between the two approaches by people tends to be polarized.  The good news is that within IDE's you can import and export modules for both types.  You can for example see/export the Verilog code that makes up a complex
.bdf module or you can convert a Verilog module into a .bdf module.

Coming from by now, years of experience using KiCAD to lay out over a 100 of S100 bus PC boards I personally found the .bdf approach of programming an FPGA very easy. Within a day or two I was up and running programming an FPGA with quite complex circuits.   This was possible because the Quartus IDE (see below), supplies libraries for things like all the common 74xx logic chips, many of the common VSLI style chips (e.g.. UARTs) etc. It contains many libraries of many extremely complex/useful modules such as CPUs.  While you can drill down for detail,  at a top level they behave as "black boxes". You just supply the wire or bus connections -- which you draw as lines.   It would take me months of learning to do the equivalent in raw Verilog code.  I will illustrate this below. 

BTW, there is one well known/subscribed source code site for FPGA's called OpenCores  where you will find an enormous list of FPGA projects/code.  There numerous other excellent FPGA code applications on the web. For example Javier Valcare's FPGA home page and fpga4fun.

Quartus Prime.
For Altera/Intel FPGA's the program of choice to program them is called Quartus Prime.  This a very large Windows based IDE interface. It is completely self contained with everything you need to write FPGA code and program the chips. Its an expensive software package. Fortunately Intel supplies a "Quartus Lite" free version for students and people like us.  Even this is way overkill for our use.  The most recent version can be downloaded from this Intel site.  The package will take ~20 minutes to install on Windows 10.  You may want to first review this video about the installing process. Please see the Notes section at the bottom of this page for more help installing Quartus.
Please keep in mind that programming an FPGA is different from the normal linear/sequential programming approach you may be used to.  On an FPGA everything is potentially happening at once.  Good FPGA programmers take years to excel and currently are in high demand.   Timing and power distributions across the chip almost become an art form.  Fortunately out needs will be far simpler.   Also there seems to be an excellent community of experienced people ready to help -- beginners.  I have found the Altera forum to be very useful and helpful.   However by far the best way to get started is to look at a few YouTube demonstrations.   

One outstanding YouTube video to get you going with Block Design File FPGA programming is this one by ClockFabrick Electronics Academy.  A text summary is provided here.  If you cannot get to that YouTube video you can directly view it in the video below.
Note, click on the "full screen icon" for easy viewing. Use ESC to return.   
Also please allow a few minutes for it to download.  It's a very large (50 minutes) video file.
For absolute FPGA beginners, rest assured,  you can more or less use the FPGA code examples below as "Black boxes" to get this board up and running. However you will be missing one major aspect of the board. By stepping along and understanding how the FPGA code works you will in the end have the ability to modify the board in amazing ways.

Before we start, a few things about our FPGA code file directory structures.   We will "build" our FPGA code in steps of increasing complexity. I have found out the hard way, that that you have to be very careful with Quartus where you place your files.  The actual Quartus "Project file" work 
80286_FPGA.qpf  should reside in the main folder you will build your programs. In my case it happens to have a path:-


The above path (in yellow) is the root below which we will build all files in this project. Your path may be different but the 80286_FPGA directory must exist. The actual Z80_FPGA.bdf in this directory is our current "work file" which when compiled we use to program the FPGA.

You will notice in the download (see bottom of this page) , numerous
80286_FPGA1.bdf, 80286_FPGA2.bdf, 80286_FPGA3.bdf...... files.  these are the main 80286_FPGA.bdf file of increasing complexity as we add FPGA components/modules  to our board.  The file 80286_FPGA.bdf is always the most sophisticated and current file constructed. It will get more complex over time. 

In every case as we build,  we first "Close" the current
80286_FPGA.bdf file it within Quartus.  Note not the project file (80286_FPGA.qpf).
We then go outside of Quartus into windows and delete (or rename) it.
We then take the next more complicated
80286_FPGAx.bdf file (80286_FPGAx+1.bdf) and rename it 80286_FPGA.bdf
We then go back to Quartus and open this
80286_FPGA.bdf file and work on it.

The key thing here is Quartus does not know we switched files on it.  This way all pin designations, ROM and RAM preloaded .HEX files remained unchanged.  Plus other things.  If you start flipping files around renaming them etc., within Quartus it gets confused -- without telling you.

I cannot stress enough the trick of saving old
.bdf files, renaming them, (outside of Quartus), along the way. This way you can easily fall back to the last good working example.  Saved my neck many times!

A few things about Quartus.

1. It constructs a number of sub-directories as it constructs its FPGA code below the 80286_FPGA directory. You don't  have to bother about them.

2. As Quartus compiles your code,  it seems to send out endless information in messages. Again don't bother about them unless it tells you (in red text) that there are errors at the end.

3. Be very careful when you place copies of a logic item. Sometimes when you click you can place one item exactly over another yet the item appears as only one unit. For example a NOT or a NOR gate. The compiler will insist the gate has no input when in fact there is a hidden gate under it.

4. Be careful when you join up and input or output port to a wire or bus line. Make sure they join by dragging them apart.

5. Some gates are negative true. I use names like pWR- to signify this. Quartus does not accept pWR*.

6. Be sure you assign actual pin numbers to FPGA inputs and outputs. Quartus does not tell you if they are unassigned.

7. As I said above build a circuit in stages of increasing complexity saving versions (outside of Quartus) along the way.

8. Be sure the designated FPGA for a new project is an EP4CE10F17C8  FPGA for the above WebShare board.

BTW, the actual compiling and programming process takes longer than you might expect (~3minutes for the complete program).

Step By Step Building the FPGA 80286 SBC Board
The build instructions are fairly simple for this board but because it is a complex board building it should not be rushed.  As always, first examine the bare board carefully for scratches or damaged traces, use a magnifying glass if need be.  A broken trace is almost impossible to detect by eye on a completed board.
Solder in all the required IC sockets, resistors, resistor arrays, capacitors, jumpers, and the Pololu 5V and 3.3V voltage regulators.  Also do not add the MicroSD Card Adaptor yet. Please be sure you put the resistor arrays in with the correct orientation of pin 1. An incorrect orientation is one of the most difficult things to detect/debug on a board if not noticed. Check their values before soldering (they are difficult to remove).  Insert all jumper arrays.  
Do NOT insert the resistor R21 (150 Ohms, under P5) or the Cap C23 (47pF beside it).  Bridge the two R21 pins with a small piece of wire.
Interrupts work more reliably without them, see below.
   C23 patch
The holes for the PS/2 keyboard socket are slightly off -- at least for the Jameco one.  The lowest two pins need to be bent slightly.  Clip off the 3 outer shell ground tags. You can just add solder to the outer shell and the board shell holes when the PS2 pins are soldered in.

Note there are two sockets for the Pololu 5V regulators. While the older ones (D24V25F5) are still available and use P1, it seems Pololu is suggesting users use the newer D24V22F5's (5V, 2.5 Amp) units, it has a different pinout, use this one in P67.  More recently they also added the equivelent D24V22F3 3.3V regulators. Unfortunately in their wisdom they again changed the pinout connections. This board is NOT set up for these 3.3V regulators.  You must use the Pololu D24V
25F3 3.3 V regulator in P4.

For sockets that have a directly soldered IC "under them" (U9, U1 and U11) you need to remove the socket plastic cross bridge with a clippers and file.

When adding the LED's be sure to orient them correctly. (Usually the longer lead in the square pad).
Please take care to not "slobber" solder on the sockets. They are very closely spaced on this board with vias often close to a socket pin - particularly for the FPGA adaptor sockets. Be sure you also orientate the buzzer and coin battery socket correctly. The + side of the buzzed in toward the bottom side of the board. Do not add the actual battery yet. Also be sure you insert the two transistors correctly.  The six PS2 Keyboard socket pins need to be slightly bent to fit.  You can clip off the outer shield ground pads, just add a drop of solder on the case sides when the pins are soldered in.
For prototype boards I generally use "double swipe" IC sockets. For a critical board like this I prefer to use "Machine Tooled" IC sockets.  However they are more expensive and you have to be particularly careful not to bend the IC pins.  Don't forget to add the small 32.768 KHz crystal
X1 below the RTC socket.
Here is a picture of the board at this stage.
    Stage 0
For testing remove every S100 bus board in your system except (if you have one, the S100 Bus SMB and/or the Bus Display Board).  If you have neither of these boards you must press the reset button (
SW1) on the board itself to run the actual FPGA program (after uploading it). As we shall see below during the software build, there are two options for the 80286 monitor console IO. If you have a Propeller Console IO Board, great, use it. If not, you will need to use the onboard USB port connected to a TTY terminal on your PC for monitor IO.  The former option is much better and far easier to get going. It will be a few steps down before you have a working USP port. Except for looking with a logic probe at critical signals you will be in a sense flying blind in that case.  Alternatively you can modify the FPGA (and later 80286 monitor) code to address your own Console IO ports.

Lets get started, Place the board as shown above in the bus without any chips  inserted, (including the Waveshare FPGA adaptor). There are two separate voltage rails on this board 5V and 3.3V. Carefully examine the schematic and check the voltage to the individual sockets are either 5V or 3.3V.  Be sure you have 3.3V and 5V going to the appropriate pins on the Waveshare FPGA adaptor socket.   5V on P7 pin 2, or P8 pin 1 will destroy the unit.

If you are comfortable with the above, solder in the two 74VLC245's U35 and U10 directly to the board. Also the 74LS05 U17. If possible use known good chips from a working board. (Removal of a dead chip here is difficult). BTW, U15 is not needed unless you later want to run the board as a bus master with bus slaves.

Carefully insert the WaveShare Cyclone IV adaptor in its sockets.   Power on the  computer.  "Virgin" Cyclone IV Adaptor boards from WaveShare seem to have the FPGA preloaded with a program (in the EPCS16 Flash RAM) that already that pulses its 4 onboard LEDs.  Note the flashing rate.

Within the Quartus FPGA project folder (the expanded
FPGA_80286.zip download, see bottom of this page), erase 80286_FPGA.bdf and copy 80286_FPGA1.bdf to 80286_FPGA.bdf.

Please note the actual 80286
_FPGA.bdf file in the above 80286_FPGA.zip download is the final (Step 10 or later steps, see below) FPGA code.  It is there only for experts that have used Quartus and know how to code FPGA's using .bdf files.  Everybody else should delete it and step things along (80286_FPGA1.bdf.bdf ,2,3...10) as we build up the board as described below. 

Let's get started...

Load Quartus and open the Project file 80286_FPGA.qpf, then open the file 80286_FPGA.bdf. When loaded, "
Compile the Design", then "Program the Device" and then hit the "Start" button.  The LED's on the Waveshare adaptor should flash differently. To confirm, kill the power and reboot the computer. The code in the FPGA is lost so the original flashing rates should reappear.   Note,  if you are using a previously programmed FPGA adaptor with code "burnt" into the FPGA the power-on flashing will probably not be present.  In fact,  Waveshare may in the future supply adaptors without the flashing code in them.   Here is a picture of the 80286_FPGA.bdf file:-
    Quartus Run 0 

Very important the LED
D1 "BOARD_ACTIVE" should be flashing.
This is your first connection of the FPGA adaptor to the outside world!  Do not go forward until you see this response.

1. The IO PORT Test.
The easiest way to get this board going is to use a real pair of  EEPROMs in the "RAM" sockets U1 and U9 with a very simple program.
We will start with this approach.  You will need some way to program a pair of AT28C256 (256K)  EEPROMs.  
If you don't have access to a PROM burner you can proceed to the next step below where we setup a PROM pair within the FPGA, but for beginners a pair of real EEPROMS builds confidence!

Lets get started.
Remove all boards in your system except the Propeller Console IO board (or an equivalent Console IO board, adjusting for the status & data ports described below).
First solder in directly to the board U31 and U15, two 74LS07s.  Again, make sure you have good chips.
First add U3,U4,U5,  U6,U7,U8,  U33,U34,   U21,U22,U29,  U23,U25,U26, and U27
Add U28 and U2. Add the 80286 CPU U12, and the Bus Controller (82288) U16.

Jumper JP1, JP2 and JP3.
Jumper the TMA jumper block, P9 1-2.

Solder directly to the board IC's U31, U15, U13, U35, U10 and U17. 
Try and use known good chips -- ideally from a previously working board. These chips would be hard to remove if faulty.
Here is a picture of the current board:-

We also need to jumper K5 2-3, K4 2-3, K6 2-3 and K7 2-3   also K8 2-3, K1 2-3,  Then JP4, JP5, and JP6,  and  finally  K3 1-2 and K2 2-3.

Please note the sockets U1 and U9 are really intended for the onboard static RAM chips (see below).
We will use two 14 pin 28C256 EEPROMs in the rightmost pins of the 32 pin sockets as shown here:-
The 2X8 bit data output from these ROMs will go directly to the CPU data input lines (via EEPROM pins D0-D7 and D8-D15). Most important at the same time any data input from the actual S100 bus data lines is inhibited via DATA_IN_OE* (U7) via ROM_SEL- in the  80286_FPGA.bdf file. It is most important that you see and understand how the FPGA distinguishes between data it sends or receives directly to/from the external CPU data lines and how in other cases the CPU sends/receives data directly from the S100 bus and sends it directly to the CPU.  As we build up the complexity of the FPGA circuits this process will get more complex. The 80286 CPU does not know or care where it is getting or sending its data -- its up to the FPGA circuits to decide.

Currently we have a very simple situation -- the CPU will simply reads the EEROMs (at FFFF0H), which tell it to continuously send 3's to the console IO port 01H:-

START: MOV    AL,33H        B0 33
       OUT    01H,AL       
E6 01
       JMP    START        

As we will also see below,  the maximum capacity for a pair or ROMs within the FPGA is 128K.  Since the are no 128K EEPROMs we will use the "top half" of ATMEL 28V256 256k EEPROMs. The above code is so simple you can directly edit the two EEPROMs using software such as that for a Wellon VP299 (or later) Programmer from here:-


and install it. (You do not need Wellon hardware to run it).  To save time however the .HEX files can be downloaded as:-

from the bottom of this page. You then need to the "Burn" these two .HEX files into the EVEN and ODD byte 28C256 EEPROMs. 
Here is the contents of the EVEN ROM.  The ODD ROM will be identical except that the 3 bytes will be
33, 01, FA.
  Low ROM Data

Next we will load the above  simple FPGA program to test that our S100 bus address, data and control lines are connected to the bus correctly.
Within Quartus, close the current 80286_FPGA.bdf file.  Note,  not the project file (80286_FPGA.qpf).
Then go outside of Quartus and into windows and delete (or rename) it.
Then take the next more complicated file, 80286_FPGA
2.bdf,and rename it 802866_FPGA.bdff
Then go back to Quartus and open this 802866_FPGA.bdfffile and study it..

We will configure the board such that it is a S100 "Bus Master".  Upon reset, the 80286 always has the S100 bus. . 
Here is the relevant section of the
80286_FPGA.bdf file.

The 80286 CPU will immediately boot from reset to
FFFF0H. Here the
CPU is in the address range between
FF800H and FFFFFH and will select the ROMs. (Because we normally will be using RAM in U1 and U9, the ROM chip selection is actually called FPGA_RAM_SEL- and FPGA_RAM_RD- in the 80286_FPGA.bdf file).
When you compile and run the 80286_FPGA.bdf file you should see the following output on your Propeller Console IO board after hitting the reset button SW2.
No other S100 boards except the Console IO board need be in the system.
    Output 3's
Also the 80286 Active LED should be on.
If you don't  have a Propeller Console IO board try whatever port you intend to use as console IO.
This is the simplest possible configuration of this board. You must get the above output working before going further.

Next we will make a small change. From now on we will configure the board for testing as a S100 bus slave.
We will modify the 80286_FPGA.bdf  as follows:
This has already been done for you in the
80286_FPGA3.bdf file.

So within Quartus, close the current 80286_FPGA.bdf file.  Note,  not the project file (80286_FPGA.qpf).
Then go outside of Quartus and into windows and delete (or rename) it.
Then take the next more complicated file, 80286_FPGA
3.bdf,and rename it 80286_FPGA.bdff
Then go back to Quartus and open this 80286_FPGA.bdfffile and study it..

Add back your Z80 Board and RAM board.
When you re-compile and load the
80286_FPGA.bdf file, with the Z80 Master "O' command (or however you lower the S100 bus
TMA0 line), you should see the same 3's output on your Propeller Console IO board..

2. Adding an FPGA ROM.
One nice thing about these FPGA's you can internally build your own ROM's. Since the 80286 has a 1M address space (in real mode) it would be nice to have a real big/elaborate ROM monitor. Alas, our Cyclone IV will allow us only room for 128K (or 2X64k) ROMS.  So we will fool the Wellon into thinking the VP299 (or later) programmer its programming a 27128 EPROM. This is still plenty to have a very elaborate monitor as we will later see. 

We will place our EEROMs at
FF800H-FFFFFH within the FPGA code.  Further to get going we will start again with the above 3's output test program -- just this time the ROM is provided by the FPGA. The actual ROM module is obtained from one of the Quartus IP libraries.  It's  important you select the Intel File format and the .HEX file ends up correctly in the correct position within the FPGA "ROMs".    The critical code is at 3FF0H to 3FFFH which in the FPGA ROMs will be FFFF0H-FFFFFH. We will use two .HEX files

Both of these files must be loaded into the FPGA ROMs correctly. I will describe how to do this in the next (more complicated) section.
I has already been done for you in the 80286_FPGA4.bdf (see below).

Remove the two "real" EEPROMS in U1 & U9 and add two HP628512LP 512K static RAMS.
Add U37 & U18.

Within Quartus, close the current 80286_FPGA.bdf file.  Note,  not the project file (80286_FPGA.qpf).
Then go outside of Quartus and into windows and delete (or rename) it.
Then take the next more complicated file, 80286_FPGA
4.bdf, and rename it 80286_FPGA.bdf
Then go back to Quartus and open this 80286_FPGA.bdf file and study it.

A lot more is going on here than you might first think.  Because the S100 bus can dynamically act as an 8 or 16 bit bus and the 80286 always sends and receives even byte data on its D0-D7 lines and odd byte data on its D8-D15 lines we have to within the FPGA direct data to/from the S100 bus.  This is done by controlling the 3 buffers
U7, U8 & U6.  You should understand the process by reading up on a write-up for our earlier RAM cards. See here and here

Again, for real experts,   I initially tried bringing these three buffers into the FPGA where only two external 74LVC
373's would be needed.  Wasted a week on it, I found at high speeds,  the CPU needed the 5V 74LS373 on the bus.

You should see the same 3's Console output you saw with the "real" EEPROMS.

While hopefully you will not need them, during development I wrote FPGA ROM Hex files to test a number of different S100 bus situations. 
They are all in the ROM_HEX_FILES directory.


We could alter the two 8 bit  FPGA ROMS to one 16 bit ROM and go with one simple .HEX file, but by having a separate LOW and HIGH ROM we can in fact use code from "real" 28C256 EEPROMS and by jumpering them as described above test the FPGA code ROMs with "real" ROMs back and forth.

3. Adding RAM and the 80286 Monitor.
Next we need to add the actual FPGA ROM 80286 monitor, but before we do this, because the monitor needs a valid stack we must add RAM access. 
While we could use an S100 bus 8/16 bit RAM, we will add 1MG of static RAM to the board. We will use two HM628512LP static RAM chips.  We have had great success with these chips in the past. You can also use the Alliance AS6C4008 chips
So add them to the U1 and U9 sockets..
We also need to jumper K5 1-2, K4 1-2, K6 1-2 and K7 1-2.

Within Quartus, close the current 80286_FPGA.bdf file.  Note, not the project file (80286_FPGA.qpf).
Then go outside of Quartus and into windows and delete (or rename) it.
Then take the next more complicated file, 80286_FPGA
5.bdf, and rename it 80286_FPGA.bdf
Then go back to Quartus and open this 80286_FPGA.bdf file and examine it.

Then load the two monitor HEX files:-
FPGA_80286_EVEN.HEX,   FPGA_80286_ODD.HEX (see below)
Compile and run the FPGA code. After a reset the 80286 monitor should boot up as shown here.
Please note a number of the menu options will not run at this stage.
     Monitor Signon
One of the most common problems I ran into building this board was loading code into the two FPGA ROMs. In theory simple enough, but it you do it often mistakes happen. It was my number one reason why a configuration did not boot. For this reason I will elaborate on the process more.

First unlike the above test programs the 80286 monitor will normally be developed/modified from the
80286.A86 source code file.  This (normally) will be in a completely different directory than your Quartus source files. You need to note where the final NASM 80286.BIN file is written.  In my case the path is:

C:\Users\John Monahan\Documents\S100\NASM\FPGA_80286 monitor\FPGA_80286.BIN
To construct the two .HEX files for the LOW/HIGH Quartus ROMs we again use the software for a Wellon VP299 (or later) Programmer from here:-


The software is setup this time to program a 27128 EEPROM.  We don't of course use an actual EPROM we just generate two .HEX files for them.
Hopefully these pictures explain the process.  First load the Even/Low Byte ROM:-
Check it "looks" OK as shown in the second picture, then save is as a .HEX file.

Then do exactly the same thing for the ODD/HIGH byte ROM. Again starting with the
FPGA_80286.BIN file, ending up with a FPGA_80286_ODD.HEX file. Note the complete path to where these two files are stored in your system.

Then within Quartus, right click on the ROMs, select "IP Parameter Editor", and when asked provide the correct path to your .HEX file as shown here:-
    Quartus Hex file Location

Do this for both FPGA ROMs. 
Please note, in the .zip file at the bottom of this page, I have copied all the above FPGA HEX files to a sub-folder within our Quartus FPGA_80286 monitor folder.
In my case its path is:-

C:\Users\John Monahan\Documents\S100\NASM\FPGA_80286 monitor\ROM_HEX_FILES

Note you only have to do this if you change the ROM .HEX filenames.  Quartus will always find and reload them for each compile of the total
FPGA_80286.bdf file.  This is both a good and bad thing.   It saves time, but if you forgot you somehow chanced the .HEX files contents a while back, the "new" files will be incorporated into your .bdf file without a warning.
Here is a picture of the board at this stage.
4.  Adding the IOBYTE Switches and Diagnostic LEDs.
As with the FPGA_Z80_SBC board we will use a bit pattern from a designated S100 I/O port to redirect the monitor I/O to various components on the board.  This concept is used throughout our S100 bus CPU boards. The default "IOBYTE Port" we will use here is port
8EH.  We will use the lower 4 bits as switch inputs. The status of these bits  can actually be read as the 4 upper bits of input port 8EH
. They could also be used for LED indicators.

While on the subject of I/O ports,  while the 80286 can address 64K of them, normally we work with the first 256  of them on the S100 bus.  To simplify the FPGA .bdf schematic further we will just use even address ports.  We will use a bunch of them together for various board components using the following circuit.
  Port Addressing
On this board in its current final form (see below), there are 4 different I/O possibilities for a Console for the 80286 Monitor (and MSDOS).
1.  The Propeller Console IO board.
2.  A USB port connected to a PC and a TTY character terminal.
3.  For both of the above,  the keyboard can instead come from a PS2 keyboard connected to the boards PS2 socket
P3 or P12
4.  For all 3 of the above,  the Console output can instead go to a VGA display connected to the boards VGA socket
J1 or P2

The decision in the 80286 monitor is based on the lower 3 bits of the 8 bit IOBYTE port. Defined as follows.
xxxxxx11 All console IO goes via the Propeller Console I/O board.  
xxxxxx10  All console IO goes via the USB port/PC TTY terminal
xxxxxx0x  Input for the console (above) is  overridden and always comes from the PS2 keyboard.
xxxxx0xx  Output for the console (above) is overridden and always goes to the onboard VGA display.

So for example if the IOBYTE port is absent/ non-functioning (11111111),  all Console IO will be via the Propeller Console I/O board.  
If the IOBYTE port is xxxxx00x the PS2 Keyboard and VGA display would be the Console.
Please note these functions have not been added yet to our FPGA code. We will do so below in stages.

For now set the dip switch
SW1 to all open. 

Within Quartus, close the current 80286_FPGA.bdf file.  Note, not the project file (80286_FPGA.qpf).
Then go outside of Quartus and into windows and delete (or rename) it.
Then take the next more complicated file, 80286_FPGA
6.bdf, and rename it 80286_FPGA.bdf
Then go back to Quartus and open this 80286_FPGA.bdf file and examine it.

Compile and run the 80286_FPGA.bdf program.

Use the 80286 monitor
E command to examine SW1 position 4 (the LHS switch).
Open you should get    
Closed you should get  
Make sure the other 3 switches are always open at this stage.
    LED SW1

We will also add the FPGA code to activate the buzzer.  The current configuration utilized port 0H. This is the Propeller Console IO board input Status port. It is not used as an output port. We will use it here where any character sent OUT to port 00H will trigger a pulse on the buzzer with the following circuit.
  Buzzer Circuit

5.  Adding a Serial/USB port
We will now add a USB Port for Console I/O to the board. 
This will be a relief to those that do not have the Propeller Console IO Board and may have been flying almost blind up to now. 
There are numerous Serial to USB converters available these days.  This board will work with these common Adfruit or SparkFun ones shown here:-
   Adaptor Sockets
All 3 fit into the socket
 P15.  I actually prefer the FT231x, but the Adafruit CP2104 brings out RTS and CTS to the bottom connector P15. This is useful for fast connections XModem etc..

This also is the first time we will be using Public Domain software modules.  As I said above, these are available for chips like the Cyclone Series in many places on the web.  I mention in particular OpenCoresJavier Valcare's FPGA home page and fpga4fun.   In most case however the source is in VHDL or Verilog "raw" format.  
Fortunately Quartus allows you to convert the module to a .bsf file so it can be used directly in our (growing) 80286_FPGA.bdf file.

In this case we use the UART.V file from OpenCores Then under the File menu:- Create\Update, Create a Symbol File from current file. We create uart.bsf.
Then within the Quartus Symbol Tool, under Project, you will find uart. Drag that into your growing .bdf file --  I always add components at the bottom.
This is how one adds software modules in Quartus.  Its already loaded for you however in our next version of 80286_FPGA
So again repeating the drill:-

Within Quartus, close the current 80286_FPGA.bdf file.  Note,  not the project file (
Then go outside of Quartus and into windows and delete (or rename) it.
Then take the next more complicated 80286_FPGA
.bdf file and rename it 80286_FPGA.bdf
Then go back to Quartus and open this 80286_FPGA.bdf file and work on it.

Here is the core circuit.
The above circuit is actually an RS232 UART circuit.   We use one of the common RS232->USB adaptors to convert the bidirectional data to a USB format. 
I like to use the SparkFun FT231x.  It's simple and reliable and uses a USB micro connection.  It can run at 5V or 3.3V.  Since we are connecting the chip to the FPGA directly you need to jumper the chip on the back to 3.3V.  Sparkfun also supplies a Sparkfun FTDI "Basic" converter, FT01, which uses the older USB mini connector -- same pin connections.
Be sure you configure either converter to 3.3V with the jumper on the back of the USB adaptor unit.

On the receiving side you will need a PC TTY terminal. Again there are many . I like the Telnet Program Absolute Telnet.  Under "Options", select "Properties", then select "Connection". Your SparkFun windows driver should appear as a COMx port. If you pull out the USB cord that COM port should disappear from the "port" dropdown menu.  It will reappear if you reconnect.  Set to 38400 baud, 1 Stop bit, No parity.  Another good Telnet program is Tera Term. This one can be downloaded for free from here

Here is a picture of the USB Port Adaptor attached to the board.
    USB Port

The default data USB data port is at
080H.  So from the 80286 monitor if you enter:-


You should see a "3" on the TTY terminal.

If you set the RHS switch of the Dip Switch's (SW3) to closed (ground) and reset the board the 80286 Monitor should sign on at the USB TTY terminal as shown below.
This is because the 80286 Monitor Console I/O routines are programmed to recognize the USB port as an option:-
    USB Signon
Only the A,D,F,G,H,J,K,M,O,Q,R,S,T,U and V commands work at this stage. 

Remember, data from the IOBYTE port and USB port will be coming into the board via the FPGA internal modules and not the S100 bus, as explained above,  we must send the data to the 80286 in data bus directly from the FPGA. We prevent the S100 bus tri-state buffers from becoming active using this circuit.
  USB port Circuit 2
BTW you only need to use a single row socket (
P15) for these USB adaptors. The side pins (P11,P16)  are not actually used.  I actually use one pin, at position #3, each side to steady the adaptor.
Unfortunately I have not yet been able to get XModem to work with this USB port.  Currently the monitor XModem command uses the USB port on our Serial IO Board as shown here:-
  XMODEM Signon

6.  Adding CPU Interrupts,  the 8259A Controller and RTC.
Unlike the FPGA_Z80 SBC and its software , 8086 systems make extensive use of interrupts.  MSDOS minimally requires interrupts for keyboard input and time updates.   While some FPGA Interrupt modules are in the public domain, I could not find a free one the exactly emulates the 8259A hardware interrupt controller.  Any interrupt hardware absolutely has to be 100% MSDOS compatible and completely reliable.  I decided to add a "real" 8259A controller chip to the board.  Its 8 data lines interface directly to the low 8 bit data lines of the 80286 -- thus setting up a fast and simple interface. We will allow for up to 8 S100 bus interrupt inputs.  Here is the core board circuit.
    8259A circuit2 
If you are not familiar with CPU interrupts and the 8259A Interrupt controller you should read more about it here.
We will initially use the Interrupt controller to respond to test the Propeller Console IO interrupt sent on the S100 pin 5
VI1* line.
For hardware first solder to the board a known functional 74LS240 (U13). Over it insert the 8259A Chip (U11).  Jumper P11 5-6.  This allows passage of the Propeller Console IO Board keyboard input interrupt to reach pin 19 of the 8259A.  On the Propeller Console IO board (V2.51), make sure P74 is jumpered 3-4.  Jumper K3 2-3 and P25 1-2.
The board should look like this.
    8259A Picture
The remainder of the circuit resides in the FPGA.

One subtle point, the 8259A requires two address for status and configuration. For all our past boards we used ports
20H and 21H (as did the IBM PC). Because the 80286 here communicates data on its even address lines on D0-D7 and for odd address lines D8-D15, we shall simplify the board circuit by using ports 20H and 22H. This way all the 8259A data goes over the CPU data lines D0-D7.   A quick check of my other 80286, 80486 etc. CPU boards with a modified version of our MSDOS Support Board confirmed that a change in the CPU ROM BIOS alone is all that is needed to run MSDOS "out of the box", i.e. unmodified.  MSDOS does not interact with the Interrupt controller directly.
So again:-

Within Quartus, close the current 80286_FPGA.bdf file.  Note,  not the project file (80286_FPGA.qpf).
Then go outside of Quartus and into windows and delete (or rename) it.
Then take the next more complicated 80286_FPGA8.bdf file and rename it 80286_FPGA.bdf
Then go back to Quartus and open this 80286_FPGA.bdf file and work on it.

You will note in this version we are now running the CPU with a clock speed of 10MHz. For reasons that are unclear to me,  booting MSDOS (see below) at low speeds (1-2MHz) does not work reliably using our IDE-CF Card Board

Bring up the monitor "L" command.  This command will test your 8259A interrupt circuit. Any character typed on the keyboard, will generate an interrupt on the S100 bus pin
VI1* which triggers the interrupt vector "keyhnd" routine in the ROM Monitor via the 8259A.  The code is described at "IRQ1 - KEYBOARD DATA READY" in FPGA_80286.A86 ROM monitor (see below).
Whatever keyboard character you type should appear on your console output.  Do not go further until you get this result.
     Keyboard Test

You should now be able to boot "standard" MSDOS from your IDE/CF Card S100 board if you have it installed with our earlier boards.
The MSDOS Support board should not be present since the keyboard interrupt is now working from this board. 
You will however not have automatic file time/date stamping yet,  that's next.

BTW you should see the INTA LED (D5) flicker each time you enter a character from the Propeller Keyboard. No other LEDs should flash.

Please note this Interrupt circuit is by far the most fragile part of this board circuit. I spent countless hours trying different options in hardware and FPGA software.  Recently I discovered that the removal of the time delay (R21/C23) made for a much more reliable circuit.  It seems you must get the sINTA signal back to the 8259A as fast as possible. For this reason R21 the 150 Ohm resistor should be replaced by a piece of wire and C23 should not be inserted.

You must get the monitor "L" command working to boot MSDOS. If you get no character displayed try changing the number of CPU wait states (see below), or speed.  For some strange reason the circuit is much more stable when the CPU "warms up" - gets hot! 

The RTC Circuit
Next we will use the USB port for MSDOS console IO.  Insert Jumper JP9.
The FPGA circuit generates an interrupt on each keystroke and sends it out on the FPGA pin
FPGA_LOCAL_INTRERRUPT*.  This is connected via the open collector gate U31F to the input pin 19 of the 8259A (U11).  This way MSDOS does not need t know where the interrupt came from.  Furthermore the resulting CPU INTA will flash both LEDs D5 and D2.

will add the Clock/Calendar Maxim DS1305 chip U14 to the board.  Also add a CR2032 3V "coin battery. Jumper P11 1-3
This is a simple, but an extremely powerful, 16 pin DIP  chip.  We previously used it in our FPGA Z80 SBC board.
It will handle almost any date/time requirement you have.  It is described in detail here
As you can see the interface can be via a SPI or I2C connection.  I have chosen an SPI interface (Pin 9 of the DS1305 to Vcc33). 
The trick was integration the interface into the MSDOS compatible ROM BIOS to get accurate time stamping on files etc.
The FPGA SPI/RTC module is already in our 80286_FPGA8.bdf file that you rename 80286_FPGA.bdf (see above).

With JP11 jumpered 1-3 we will bring in a
18.19Hz interrupt to pin 18 of the 8259A.  This is the same "timer pulse" the original PC used in its BIOS to keep track of time.
Its important to note that  MSDOS only uses this pulse to increment a counter in RAM.  That simple and rapid counter tracks if the operating system crossed a midnight boundary.  When that happens the current date must be updated. MSDOS gets the actual date/time directly from the RTC via software interrupts. It would slow the system down too much to get the actual time and date from the RTC chip on a regular basis!

When you first boot up the system you must initialize and set the data and time with the 80286 monitor "
E" command. 
You can also do it within MSDOS with the
date and time command prompts.  Here is an example setup:-
   Set Time
Now when you load MSDOS the time will be correct.
        MSDOS Time

I should point out that over time the displayed time can be a few minutes off in 24 hours. I have not debugged this yet. It's possibly due to the FPGAs 50mHz crystal instability.

You can see now that the LED D1 is now flashing continuously.  This is because the CPU is sending back INTA's 18 times a second to the 8259A.  Any INTA's due to the keyboard int from the Propeller Console IO board is "buried" in these flashes.  It of course can be seen as a flash on the Propeller Console IO board itself.  INTA's from the USB port (and as we will see later) the PS2 keyboard port since they are generated within the FPGA will flash LED D2.

Below there is a folder of files (FPGA_80286 Support Tests.zip ) I used independent of the onboard ROM to test the RTC chip (and other things). 
They are listed as .A86 and .bin files.   There is some extra stuff in the folder you can ignore.
The relevent file is
80286_SPI_RTC.A86 and 80286_SPI_RTC.bin.  The file runs as is, at 500H in RAM.   To load it use the 80286 monitor "W" command,  with the load location 0000H. (not 500H).
Then use the 80286 monitor "G" command with the Segment = 0H, Offset =500H. 
Remember this program is running as is in the onboard RAM not the S100 bus RAM.

7.  Adding the PS2 Keyboard and VGA Video Interface.
As an alternate for the Z80 Monitor CONSOL input we will add a PS2 Keyboard for input and a VGA Video display option for output. 
If bit 1 of the IOBYTE switch is 0 then all Console input will come from the PS2 keyboard socket (see above).
If bit 2 of the IOBYTE switch is 0 then all console output will go to the VGA socket.
Within Quartus, close the current 80286_FPGA.bdf file.  Note,  not the project file (80286_FPGA.qpf).
Then go outside of Quartus and into windows and delete (or rename) it.
Then take the next more complicated 80286_FPGA9.bdf file and rename it 802860_FPGA.bdf
Then go back to Quartus and open this 80286_FPGA.bdf file and understand it.

Examine, compile and run the 80286_FPGA.bdf file.

Both the PS2 and VGA modules have been described and used with our V2 FPGA board.  Please see here for the PS2 module and here for the VGA module.

Both circuits are imported unchanged.  The only modification to the original 80286_FPGA.bdf file is we need to allow the VGA data and cursor data to go directly to the 80286 by again modifying the S100 Bus interface.    Here is a picture of the cable connections
   PS2 and VGA Connections
Note both the PS2 and VGA outputs can be connected to ribbon cables and connected to the back of your S100 Box. The pin-out is the same as for our earlier boards.
Here is the VGA Signon image you should get upon reset:-
   VGA Display
   Pin Connections
The above two modules do illustrate the power of these FPGA's. Such a circuit with standard TTL/CMOS chips would easily consume a whole S100 board!

Remember however that this redirection of Console output works within the 80286 Monitor.
If you load MSDOS or other software that does not use the standard MSDOS/IBM PC BIOS interrupts/calls they too will have to examine the IOBYTE port for data redirection.

Wait States.
The 80286/82288/8259A chip seems to be quite timing sensitive.  With an all Intel chip setup (8mHz 80286, 10 MHz 82288 and an 8259A-5) at 10 MHz the board runs rock solid with 2  wait states on all IO cycles. (No wait states for the onboard RAM/ROM  & sINTA).  Here is the FPGA wait state generator.
   Wait States
The interrupt circuit is the most "fragile" part of the board. If you run into problems lower the clock speed and/or change the number of wait states. Surprisingly low clock speeds (2-4mHz) are unstable. The timer interrupt really hammers the circuit at 18 ints/sec.

8.  Adding The SD Card Interface.
This is perhaps the most complex aspect of this board.  Not only in terms of the software but because today SD cards come in all shapes and sizes.  There are numerous articles on the web describing how to determine the type of SD card present and even more articles describing how to "initialize" them.  Three good articles that help me a lot are:

Secure Digital (SD) Card Spec and Info
What is the correct command sequence for microSD card initialization in SPI?
and the excellent code example by CC Dharmani, see here

The interface is a complete transplant from the FPGA Z80 SBC board.  The code below will read and write to today's very common Type 2 SD cards.  It would have to be modified to work with the older Type 1 cards.  These require a different initialization sequence.  Experienced SD programmers may note during the card initialization sequence I add valid CRC bytes to the initialization commands before turning off CRC checking.  I also actually set the sector size to 512 bytes .  Many programs do not do this but the are reports of some Type 2 SD cards actually requiring these steps.

As to the actual Type 2 cards themselves, they come in two sizes of "Micro" adaptors.  This board can use one Adfruit Micro SD adaptor (P18) and one SparkFun Micro SD adaptor (P17). On the back of the board a SparkFun larger SD/MMC Adaptor is added (P29).  In other words you can have three SD card drives A, B  & C. You just have to adjust the heights of the connector sockets P17 and P18 and pins so the SparkFun micro SD adaptor fits under the Adfruit Adaptor.
   SD_Card Adaptors 

Because we are interfacing the SD card with our 3.3v FPGA we can essentially connect the SD card directly to the FPGA. This is what these adaptors do.  The Adfruit adaptor runs with the 3.3V supply pin input.

Drive A: SparkFun SD/MMC Adaptor
Drive B: Adfruit Micro SD Card Adaptor
Drive C: SparkFun Micro SD Card Adaptor

As I said above, the board can accomidate a total of 3 SD cards. The small SparkFun Micro SD card adaptor can be soldered in directly to P17.  Using a single row 8 pin socket you can insert the Adfruit Micro SD Adaptor over it in P18.  On the back of the board you can attach the SparkFun SD/MMC adaptor, P29.  Here is a picture of the latter.
    SD Card back of Board
The actual P29 pin holes on the board are small enough that at least for testing you don't need to actully solder the pins in place.  The pins sticking out on the front of the board are use for attaching logic probe connectors etc.
BTW, in my hands at least,  I have always found that the SparkFun SD/MMC adaptor was the easiest  to configure and get going with software.  On this board it is configured as the "A:" drive in the default FPGA .bdf software/hardware and the 80286 monitor ("Y" command).

Using an FPGA really illustrates the utility of these FPGA chips.  We use our now tried and true SPI interface to talk to the SD cards.  Here is the core SD card SPI interface module.
It's the same as the one we used for our FPGA Z80 SBC. We will allow for three slave/SD drives. These are selected outside the above module by outputting a bit to the CS*  pin of the SD card (SD_CS_STATUS-)

You will note that we use two SPI clock frequencies.  This is because during a cold start, SD cards only communicate over the SPI lines at a slow (~100-200KHz). Once Initilized, this can be jacked up. I use
10 MHz here.  The 21mux controls this by a high/low bit from the SPEED_PORT.
We will require four I/O ports:-


SD_DATA_IN      EQU    SD_CARD_BASE     ; (78H) Data from SD CONTROLLER
SD_CS_PORT      EQU    SD_CARD_BASE+4   ; (7CH) SD Card CS* Select Port
SD_STATUS       EQU    SD_CARD_BASE+2   ; (7CH) SD CARD Status Port
SD_RW           EQU    SD_CARD_BASE+3   ; (7EH) Port to pulse SPI Read/Write interface

Initialization of Type 2 SD Cards.
You can skip this section if you like since what is here is already in the
Z80 SD_CARD software describe here.

In order to use an SD card you must first "initialize" it.  This requires a series of 48 bit SPI commands.  These must be sent in the correct sequence, not continuing forward until the correct response from the previous command is obtained.  Sometimes this involves repeated sending of a command. 

The commands themselves all have the following structure.
  SD_card SPI Format 
The first byte contains the actual "Command". All SD card commands have the following format
Here is a list of the commands we use:-

CMD_0:   DB 40H,00H,00H,00H,00H,95H,0FFH ;   (0+64)  CMD0   To Reset the SD Card interface,
CMD_1:   DB 41H,00H,00H,00H,00H,0F9H,0FFH ;  (1+64)  CMD1   Activate Init Process
CMD_8:   DB 48H,00H,00H,01H,0AAH,87H,0FFH ;  (8+64)  CMD8   To check Card Voltage
CMD_9:   DB 49H,00H,00H,00H,00H,8FH,0FFH ;   (9+64)  CMF9   Read SD Register (CSD)
CMD_13:  DB 4DH,00H,00H,00H,00H,081H,0FFH ;  (13+64) CMD13  Get SD card status
CMD_16:  DB 50H,00H,00H,02H,00H,081H,0FFH ;  (16+64) CMD16  Set Sector size to 512 Bytes
CMD_17:  DB 51H,00H,00H,00H,00H,0FFH,0FFH ;  (17+64) CMD17  Read a single block (Block 0, Used to load boot sector only)
CMD_41:  DB 69H,40H,00H,00H,00H,077H,0FFH ;  (41+64) CMD41  Activates the card's init. process.
CMD_55:  DB 77H,00H,00H,00H,00H,065H,0FFH ;  (55+64) CMD55  Application specific command NEXT
CMD_58:  DB 7AH,00H,00H,00H,00H,0FDH,0FFH ;  (58+64) CMD58  Read SD Cards OCR register
CMD_59:  DB 7BH,00H,00H,00H,00H,0FDH,0FFH ;  (59+64) CMD59  Turn off CRC checking

You will note there is always a "stuffer" byte 0FFH byte sent before a return response byte(s)  from the SD Card.  The return Flag byte contains the error code if any.  Generally (but not always),  you want to receive 00H.

The sequence to initialize Type 2 SD cards is as follows.

Drive the
CS* pin from high to low
Send 24 or more dummy
0FFH bytes.
Then send the following 6-byte command,  First byte:
0x40 (CMD0), Next four bytes: 00000000H, then the CRC byte (95H), then send another dummy byte 0FFH byte.
Read the returned byte from the SD Card.  If its not
01H,  repeat this command until 01H is returned.
This means the card is in the "idle state" and we are good to go.

Next send the following 6-byte command,  First byte: 0x48 (CMD8), Next four bytes: 000001AAH, then the CRC byte (87H), then send another dummy byte 0FFH byte.
Read the returned byte from the SD Card.  If it is 01H you probably have a
Type 1 SD card. We want a 05H returned, indicating a Type 2 card.
We confirm this by reading the next 4 bytes from the SD card.  If its 000001AAH, we have a Type 2 card for sure.

Next we "activate" the
Type 2 card by sending two back to back commands CMD55 and CMD41 exactly as done above for the CMD0 command.
Repeat the latter two commands continuously until you get a return
0H byte.

The SD card specifications says that only
CMD0 and CMD8 should have a valid CRC byte in SPI mode, however there are reports that some SD cards (like Transcend ones) seem to require a proper CRC for CMD55/CMD41 commands as well. To be on the safe side I add the byte.
Also between every command above,  the SD card
CS* line needs to be lowered and raised when done.

Based on other web postings, I also send
CMD59 to specifically turn off CRC checking and CMD16 to set the sector size to 512 bytes/sector. 
I'm not convinced these are essential but it's best to play safe.
Here is an example picture of the main SPI signals using the
CMD8 command:
  SD Card Signals 
I have written a small 80286  program to initialize, read and write sectors to the A,B and C SD drives. It is called
SD_CARD.A86. And can be downloaded at the bottom of this page.  Again, this is a standard S100 bus program that can be downloaded from your PC via the FPGA monitors "X" command.  It starts in RAM at 0H. So we use 0.  The program allows you to test the SD Cards interface.
Here is a picture of the main menu:-
Please note this is not a "bullet proof" program. Little command error checking etc. is done.  The sector numbering is only
0-FFFFH, but that should be enough for most needs.  In fact some older Type 2 cards may not accept a sector number this large. 

Note. These SD cards can read and write multiple sectors with a single SPI command. I have not added this feature yet.
Also keep in mind  the SD cards LED D6 will only light up if a SD card is not inserted in the Adfruit Micro SD adaptor (P18).  It is not connected to P17 or P29.

Of course before you run the above program you need to add the above SD Card interface module to our growing FPGA program. 

Within Quartus, close the current 80286_FPGA.bdf file.  Note,  not the project file (80286_FPGA.qpf).
Then go outside of Quartus and into windows and delete (or rename) it.
Then take the next more complicated80286_FPGA10.bdf file and rename it 80286_FPGA.bdf
Then go back to Quartus and open this 80286_FPGA.bdf file and work on it.

Examine, compile and run the 80286_FPGA.bdf file. 

Do spend some time studying the FPGA ports and the above 80286 code. 
All the critical routines: 
Initialize, Read Sector, Write Sector etc. are written as self-contained returnable calls which should make it easier to incorporate them as a MSDOS BIOS etc.
The source is in .A86 format for use with NASM.

This program is transplanted almost unchanged into our  FPGA ROM monitor and is brought up with the 'Y' command in the main menu:-
  SD Card Menu

You therefore can have 3 different SD card drives running on this board.  Currently the SparkFun SD/MMC adaptor (P29) is configured as the A: drive.
You can change the monitor drive equates and the FPGA.bdf module to switch them around (bits 0,1,& 2 of the

You can also of course boot MSDOS (Monitor 'P' Command ) from your S100 bus .
Currently I have not modified the FPGA ROM monitor to load MSDOS from the SD cards (for the IDE/CF card board it is already done).  Volunteers needed -- everything in hardware is there!

One final note, a useful PC program to see/check what is written on any sector of an SD Card is HxD Hex Editor.
It can be downloaded from here.

Burning FPGA Code to Flash RAM

Up until now whenever we programmed our FPGA via  the JTAG socket the data is lost whenever the power is turned off.   While fine for code development etc. it is not desirable for a final board configuration.  Like most FPGA applications the "final" code is saved in Flash RAM and immediately loaded by the FPGA each time upon power-up.  This is a standard and common characteristic of most FPGA's. Some older models in fact had a ROM onboard.    Our Cyclone IV Adaptor board has 16MB of Flash RAM on board for this purpose -- way more than we are ever going to need!

The tricky part is programming this Flash RAM.  I found the Intel documentation poor and confusing.  Here is a summary of the process: 
Within Quartus you need to "convert" your normal JTAG FPGA .sof programming file to a special file .jic to program the Serial Flash RAM chip on the Weveshare board.

Within Quartus, click on the File Menu and select "Convert Programming files". The dialog box below will popup.
From the dropdown box on the "Programming File Type"  select a .jic file type.
This is the file format that is required to program the onboard serial Flash RAM.
For the Options/Boot info select EPCS16. Leave Active Serial as is.
You can name the .jic output file anything you like. I usually just leave it output_file.jic.
Note it will be in the Quartus generated "output_files" folder within your work directory.

Next click on Flash loader within the lower "Input Files to Convert", then click on the highlighted "Add Device" button.
You will get a popup dialog box as shown below.
Select Cyclone IV  and EP4CE10.  Note Quartus takes some time to allow you to actually select these options -- seems to be doing things in the background!
Next click on "SOF Data" and "Add File".  You should see your "normal" FPGA program .sof file in your "output_files" folder within your work directory.
Finally click the "Generate" button.
You should get a popup dialog saying "Generated output_file.jic successfully.
Note the name and location of the converted file. Then close that dialog box.  See the pictures below.
    Programming 1     Programming 2
Programming 3 Programming 4
Programming 5
Next we need to actually flash the Waveshare boards RAM chip.
Click on the normal "Program Device (Open Programmer)" you normally use. If its not already open,  give it time to come up as a dialog box.
Make sure your board has power.  To be safe click the Auto Detect button. your normal xxx.sof file should display with the device set as EP4CE10F17.

First delete the above line xxx.sof  |  EP4CE10F17 etc.
Click on Add File and select the xxx.jic file you just generated above.
Click on the Program/Configure little square character boxes.
The chip diagram below should show only 2 chips as shown. If more right click on any 'extra' one and delete it. The dialog box must look as shown below.
The Start button should highlight.
Click on this and you will flash the RAM chip.  Follow the Progress bar until it is done -- it takes about 1 minute.
You can power off and re-power your computer.
Your FPGA board should (after reset), start with whatever FPGA code is within the chip.
Programming 8
Note when you close the above dialog box, normally you do NOT save the changes.
Typically you want the chip to be quickly reprogrammable.



No hardware changes have been noted to date. The pictures of the board on this page is actully that of the final prototype board. The actual "production" board has some very minor changes -- mostly silk screen text changes. However I have added pins (P29) to attach a SparkFun SD/MMC card adaptor to the back of the board for an extra SD drive (between U37 and U34).  Note pin 1 is on the RHS on the back of the board.


Over time there may be corrections/additions to the 80286 monitor or FPGA .bdf files. Alway check below and use the most recent versions.


A Self Contained Board

This Board is a completely self contained S100 Bus Master as defined by the IEEE-696 Specs.  It can therefore be run outside the S100 bus if you simply provide power to it.  There are two pins P20 for ground and P21 for 8-10V input to do this.  Please use the upmost care in doing this. Make sure the board is sitting on an insulated background (glass/wood etc.).    Of course you will want to configure the IOBYTE to the USB port or VGA and PS2 keyboard.



There appears to be a few variations of the 74LVC245 20 pin DIP level Shifters chips with "A", "AN" etc. after the 245.   As best I can tell so long as they are 20 pin DIPs they are all OK. I use Mouser chips # 595-SN74LVC245AN.  

The WaveShare Cyclone IV adaptor can be obtained directly from Waveshare
You also might want to get the USB Blaster/Programmer from them.

The WaveShare unit uses unusual 2mm dual row pin connectors. See the write-up above. The best sockets are the Digi-Key #1212-1786-ND 100 pin sockets (carefully clipped to size).

The USB serial Adaptor is from Sparkfun F1231x.  The Micro SD Card adaptor is from Adafruit.

Please note the sockets for the WaveShare adaptor are quite tricky to fit on to the board.  I found the best way to do it is (after trimming to size), push them half way on to the adaptor pins and then wiggle them to fit the whole unit on to the S100 board.  Figure on spending 10 minutes on this step!  Do not solder them to the board first and then try and press the adaptor down on them. They are very fragile and internally the leaves will bend if socket angles are not exactly correct.  When in place, check each pin is visible on the back of the board before soldering.  Only then solder all around.  Add as little solder to each pin as possible - the narrow pins have a tendency to wick up solder internally. 

To remove the adaptor,  leaver each corner up a little going round and round. The first time its quite difficult to get the adaptor out. It gets easier with time.
Installing Quartus Lite on Windows.
In spite of its name the
Quartus Lite IDE is a large program.  When fully installed the Quartus folder is over 15GB in size.  Installing it makes Microsoft's Visual Studio seem lightening fast! 
That said,  its an excellent IDE.  Figure on 1 hour to install and get it right.  For our purposes we will only be using probably 5% of its capabilities, but I have found if you try and get smart by not downloading or removing sections you run into problems later during usage. 

Please see here for instructions on how to install Quartus.

Building the FPGA Z80 SBC Board as an S100 bus Master CPU Board.
It is relatively easy to reconfigure the above 80286_FPGA SBC board to act as an S100 bus master board where you would boot up upon reset (with no other CPU or RAM board in the system).   If you use the USB port or VGA/PS2 port configuration you don't even need the Propeller Console IO Board.  To boot MSDOS you would need the IDE CF Card board or code for MSDOS on the onboard SD cards.  Here is the simple FPGA mods for a bus master setup.
   Master Configuration
Note to add slaves to the system with the 80286 FPGA SBC you will have to modify the 80286_FPGA.bdf file further.

Its very important not to get the Quartus/FPGA directories and files mixed up with those for those described above.
They should reside in a directory such as:-

You have to be very careful with file associations Quartus uses during compiling. If strange things happen close the program completely and start again.
A Production S-100 Board
Realizing that a number of people might want to utilize a board like this together with a "group purchases" by people on the  Google Groups S100Computers Forum was performed. It is now closed. Those currently on the order list can be seen here.

At a later date a second batch of boards may be done by Todd at:- https://www.retrobrewcomputers.org/doku.php?id=board inventory

Please see here for more information about this and other past S100 Boards.  Please do not contact me directly. 

FPGA 80286 SBC (V1.0).zip                                               This .zip file contains all the KiCAD components required to build this S100 board   (V1.1  6/17/2020)
FPGA 80286 SBC (V1.0)  Gerber.zip                                   Gerber files to manufacture the board. 
FPGA_80286_SBC (V1.0) Schematic Pdf file                        
Board Schematic    (V1.0  5/8/2020)

Main Quartus 80286 SBC Folder (Build Steps 0-10).zip         This .zip file contains the FPGA_Z80 build steps 0 to 10 described above     (V1.1  6/17/2020)
FPGA_80286 Monitor.zip                                                  This .zip file contains the 80286 monitor and FPGA .HEX files       (V1.32   6/17/2020)  
FPGA_80286 Support Tests.zip                                          
This .zip file contains the RAM based programs to test the RTC and SD card Modules       (V1.0   6/17/2020)
 This is a .tar file containing Quartus Lite and support programs. Note it's almost 6GB in size    ( V1.31   6/9/2020) 
FPGA_80286 SBC BOM (.pdf)                                             Supplied by Rick Bromagem (V1.0  6/17/2020)
FPGA_80286 SBC BOM (.xls)                                              Supplied by Rick Bromagem (V1.0  6/17/2020)
FPGA_80286 SBC Board Picture (.jpg)
                                Supplied by Rick Bromagem (V1.0  6/17/2020)
FPGA_80286 SBC board Layout (.pdf)                              
  Supplied by Rick Bromagem (V1.0  6/17/2020)

Other pages describing my S-100 hardware and software.
Please click here to continue...

This page was last modified on 08/11/2023