https://spectrum.alioth.net/doc/api.php?action=feedcontributions&user=Winston&feedformat=atomSpectrum - User contributions [en]2024-03-28T20:06:58ZUser contributionsMediaWiki 1.37.1https://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=434Main Page2022-11-29T09:41:58Z<p>Winston: /* Latest News */</p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! Currently, Ben Versteeg of [https://bytedelight.com Byte Delight] is building and selling the Spectranet. There is also a Facebook group run by Ben [https://www.facebook.com/groups/317751018885010/ Spectranet Facebook group]. Ben's YouTube channel (linked from his site) also has a bunch of interesting videos, including the pick-and-place assembly machine used to build the boards.<br />
<br />
Additionally you may find stock at [http://www.sellmyretro.com/ RWAP Software] (who also sells other useful items like replacement keyboard membranes), who sold the Spectranets assembled from around 2014 to 2016.<br />
<br />
2022-06-04: [[Make a Chip Pro]], an FPGA board for the Spectrum is under development.<br />
<br />
2020-02-21: By popular demand, project sources etc. are now available on Github: see https://github.com/spectrumero/spectranet .<br />
<br />
'''Latest Spectranet firmware''': R600 (released 30th November 2020)<br />
<br />
'''Speccytools''': https://speccytools.org/ Development tools that use the Spectranet - debugging tools, emulators etc.<br />
<br />
'''Spectranet TNFS resources index''': https://speccytools.org/index/ (source code: https://github.com/speccytools/spectranet-index-module )<br />
<br />
'''Spectrum Channels Protocol API''': A new way of building internet-enabled software for the Spectrum, by desertkun: see https://github.com/speccytools/zx-proto<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Make a Chip Pro]] - FPGA add-on for the Spectrum, like the [[ZX Breakout]] but with more stuff. For the Spectrum's 40th anniversary!<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [https://github.com/spectrumero/spectranet GitHub] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=433Main Page2022-11-29T09:38:37Z<p>Winston: </p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! Currently, Ben Versteeg of [https://bytedelight.com Byte Delight] is building and selling the Spectranet. There is also a Facebook group run by Ben [https://www.facebook.com/groups/317751018885010/ Spectranet Facebook group]. Ben's YouTube channel (linked from his site) also has a bunch of interesting videos, including the pick-and-place assembly machine used to build the boards.<br />
<br />
Additionally you may find stock at [http://www.sellmyretro.com/ RWAP Software] (who also sells other useful items like replacement keyboard membranes), who sold the Spectranets assembled from around 2014 to 2016.<br />
<br />
2022-06-04: [[Make a Chip Pro]], an FPGA board for the Spectrum is under development.<br />
<br />
2020-02-21: By popular demand, project sources etc. are now available on Github: see https://github.com/spectrumero/spectranet .<br />
<br />
'''Latest Spectranet firmware''': R600 (released 30th November 2020)<br />
<br />
'''Spectranet TNFS resources index''': https://speccytools.org/index/ (source code: https://github.com/speccytools/spectranet-index-module )<br />
<br />
'''Spectrum Channels Protocol API''': A new way of building internet-enabled software for the Spectrum, by desertkun: see https://github.com/speccytools/zx-proto<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Make a Chip Pro]] - FPGA add-on for the Spectrum, like the [[ZX Breakout]] but with more stuff. For the Spectrum's 40th anniversary!<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [https://github.com/spectrumero/spectranet GitHub] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=432Main Page2022-11-29T09:37:56Z<p>Winston: </p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! Currently, Ben Versteeg of [https://bytedelight.com Byte Delight] is building and selling the Spectranet. There is also a Facebook group run by Ben [https://www.facebook.com/groups/317751018885010/ Spectranet Facebook group]. Ben's YouTube channel (linked from his site) also has a bunch of interesting videos, including the pick-and-place assembly machine used to build the boards.<br />
<br />
Additionally you may find stock at [http://www.sellmyretro.com/ RWAP Software] (who also sells other useful items like replacement keyboard membranes), who sold the Spectranets assembled from around 2014 to 2016.<br />
<br />
2022-06-04: [[Make a Chip Pro]], an FPGA board for the Spectrum is under development.<br />
<br />
2020-02-21: By popular demand, project sources etc. are now available on Github: see https://github.com/spectrumero/spectranet .<br />
<br />
'''Latest Spectranet firmware''': R600 (released 30th November 2020)<br />
<br />
'''Spectranet TNFS resources index''': https://speccytools.org/index/<br />
<br />
'''Spectrum Channels Protocol API''': A new way of building internet-enabled software for the Spectrum, by desertkun: see https://github.com/speccytools/zx-proto<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Make a Chip Pro]] - FPGA add-on for the Spectrum, like the [[ZX Breakout]] but with more stuff. For the Spectrum's 40th anniversary!<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [https://github.com/spectrumero/spectranet GitHub] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=431Main Page2022-10-27T08:22:36Z<p>Winston: /* Latest News */</p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! Currently, Ben Versteeg of [https://bytedelight.com Byte Delight] is building and selling the Spectranet. There is also a Facebook group run by Ben [https://www.facebook.com/groups/317751018885010/ Spectranet Facebook group]. Ben's YouTube channel (linked from his site) also has a bunch of interesting videos, including the pick-and-place assembly machine used to build the boards.<br />
<br />
Additionally you may find stock at [http://www.sellmyretro.com/ RWAP Software] (who also sells other useful items like replacement keyboard membranes), who sold the Spectranets assembled from around 2014 to 2016.<br />
<br />
2022-06-04: [[Make a Chip Pro]], an FPGA board for the Spectrum is under development.<br />
<br />
2020-02-21: By popular demand, project sources etc. are now available on Github: see https://github.com/spectrumero/spectranet .<br />
<br />
'''Latest Spectranet firmware''': R600 (released 30th November 2020)<br />
<br />
'''Spectrum Channels Protocol API''': A new way of building internet-enabled software for the Spectrum, by desertkun: see https://github.com/speccytools/zx-proto<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Make a Chip Pro]] - FPGA add-on for the Spectrum, like the [[ZX Breakout]] but with more stuff. For the Spectrum's 40th anniversary!<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [https://github.com/spectrumero/spectranet GitHub] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Make_a_Chip_Pro&diff=430Make a Chip Pro2022-07-19T15:24:44Z<p>Winston: </p>
<hr />
<div>== Latest news ==<br />
<br />
The board's FPGA side has been tested, showing the serial flash, static RAM, power supplies, and the FPGA itself is working. This project is a work in progress.<br />
<br />
== Purpose ==<br />
<br />
Remember "Make a Chip?" The software for the ZX Spectrum often put on eBay as "Very r@re!!1" by sellers?<br />
<br />
Make-a-Chip was software by Icognito Software which allowed you to design (and test) some simple logic circuits at about the scale of 74-series jelly bean logic (up to about a dozen logic gates). Back in those days, at home, we had no way of actually synthesising these circuits (other than buying some said 74-series logic and connecting it together on a breadboard, to the design we may have done in Make-a-Chip). Or you could realise your design in a PAL chip, an early incarnation of a chip you could put your own circuit design on at home, although the equipment back then to do that was a bit costly and awkward.<br />
<br />
These days, things are very different. We have a plethora of capable programmable logic devices - from the CPLDs (some of which are big enough to implement a Spectrum ULA) the FPGA (field programmable gate array) which tend to have rather more resources, and often have some additional onboard circuits such as phase locked loops and block RAM.<br />
<br />
This project has been named "Make a Chip Pro", as I'm building it not to specifically implement some project, but to be a board for developing ''other'' projects that add an FPGA to our favorite 8 bit system.<br />
<br />
== The board ==<br />
<br />
The board hosts a Lattice iCE40 HX4K FPGA (in a 144 pin TQFP package), up to 512k of static RAM, a serial flash ROM for the FPGA's configuration (with plenty of storage left over for other uses), a crystal oscillator for timing, plus the power supplies needed for the FPGA. It has 25 GPIO pins brought out to a header, where other devices can be connected to the FPGA.<br />
<br />
Nearly all modern chips work at 3.3 volts and below, and are not tolerant of the 5 volt signals used by older hardware like the Spectrum, so it also necessarily must include level shifting components. All the important Z80 signals are buffered with bidirectional buffers where necessary (including the address bus, so DMA is possible).<br />
<br />
=== Why the Lattice iCE40 ===<br />
<br />
The iCE40 is a straightforward, low-cost FPGA and it's one of the best documented FPGAs that are available. Unfortunately, manufacturers tend to keep their programming bitstreams secret, which is unfortunate, as you are forced to use their (often bloated) IDEs to develop for them. SiliconBlue (which was bought by Lattice) by contrast, fortunately published the programming bitstream for the iCE40 range. The iCE40 range is also quite straightforwad - it literally is just a sea of logic blocks, some synchronous semi dual ported block RAM, and a couple of PLL blocks. There is also quite a capable chip (in the form of the iCE40 HX4K TQ144) that is in a package that can be hand soldered. Another great thing about the iCE40 is that you're not expected to use JTAG to program it - everything's done through SPI, so a cheap and cheerful Adafruit FT232H board can be used as the programmer.<br />
<br />
You can use the Lattice proprietary IDE if you like, but you can also use the open source Icestorm toolkit.<br />
<br />
One thing that Lattice won't tell you about the iCE40 HX4K TQ144 is that really it's an HX8K device in a TQFP 144 package :-) And the open source tools will treat it as an HX8K.<br />
<br />
=== What can you fit in the chip? ===<br />
<br />
My experimentation so far shows that a basic 65C02 'system on a chip' with a memory controller, some hardware for debugging, a 32-bit timer, an SPI interface, a 9600-baud UART and some other small devices only takes a third of the logic resources. You could easily implement something like a RISC V processor on the chip. There is 16kbytes of block RAM, so you could implement something like a ULA Plus with RGB out on the board.<br />
<br />
=== GitHub repositories ===<br />
<br />
The repo for the hardware (kicad files) is here: https://github.com/spectrumero/macp<br />
<br />
The 65C02 that I've been using in various tests is here: https://github.com/spectrumero/verilog-65C02<br />
<br />
[[Category:Make a Chip Pro]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=429Main Page2022-06-04T09:51:19Z<p>Winston: /* Latest News */</p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! Currently, Ben Versteeg of [https://bytedelight.com Byte Delight] is building and selling the Spectranet. There is also a Facebook group run by Ben [https://www.facebook.com/groups/317751018885010/ Spectranet Facebook group]. Ben's YouTube channel (linked from his site) also has a bunch of interesting videos, including the pick-and-place assembly machine used to build the boards.<br />
<br />
Additionally you may find stock at [http://www.sellmyretro.com/ RWAP Software] (who also sells other useful items like replacement keyboard membranes), who sold the Spectranets assembled from around 2014 to 2016.<br />
<br />
2022-06-04: [[Make a Chip Pro]], an FPGA board for the Spectrum is under development.<br />
<br />
2020-02-21: By popular demand, project sources etc. are now available on Github: see https://github.com/spectrumero/spectranet .<br />
<br />
'''Latest Spectranet firmware''': R600 (released 30th November 2020)<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Make a Chip Pro]] - FPGA add-on for the Spectrum, like the [[ZX Breakout]] but with more stuff. For the Spectrum's 40th anniversary!<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [https://github.com/spectrumero/spectranet GitHub] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Make_a_Chip_Pro&diff=428Make a Chip Pro2022-06-04T09:41:49Z<p>Winston: Created page with "== Latest news == The board's FPGA side has been tested, showing the serial flash, static RAM, power supplies, and the FPGA itself is working. This project is a work in progress. == Purpose == Remember "Make a Chip?" The software for the ZX Spectrum often put on eBay as "Very r@re!!1" by sellers? Make-a-Chip was software by Icognito Software which allowed you to design (and test) some simple logic circuits at about the scale of 74-series jelly bean logic (up to about..."</p>
<hr />
<div>== Latest news ==<br />
<br />
The board's FPGA side has been tested, showing the serial flash, static RAM, power supplies, and the FPGA itself is working. This project is a work in progress.<br />
<br />
== Purpose ==<br />
<br />
Remember "Make a Chip?" The software for the ZX Spectrum often put on eBay as "Very r@re!!1" by sellers?<br />
<br />
Make-a-Chip was software by Icognito Software which allowed you to design (and test) some simple logic circuits at about the scale of 74-series jelly bean logic (up to about a dozen logic gates). Back in those days, at home, we had no way of actually synthesising these circuits (other than buying some said 74-series logic and connecting it together on a breadboard, to the design we may have done in Make-a-Chip). Or you could realise your design in a PAL chip, an early incarnation of a chip you could put your own circuit design on at home, although the equipment back then to do that was a bit costly and awkward.<br />
<br />
These days, things are very different. We have a plethora of capable programmable logic devices - from the CPLDs (some of which are big enough to implement a Spectrum ULA) the FPGA (field programmable gate array) which tend to have rather more resources, and often have some additional onboard circuits such as phase locked loops and block RAM.<br />
<br />
This project has been named "Make a Chip Pro", as I'm building it not to specifically implement some project, but to be a board for developing ''other'' projects that add an FPGA to our favorite 8 bit system.<br />
<br />
== The board ==<br />
<br />
The board hosts a Lattice iCE40 HX4K FPGA (in a 144 pin TQFP package), up to 512k of static RAM, a serial flash ROM for the FPGA's configuration (with plenty of storage left over for other uses), a crystal oscillator for timing, plus the power supplies needed for the FPGA. It has 25 GPIO pins brought out to a header, where other devices can be connected to the FPGA.<br />
<br />
Nearly all modern chips work at 3.3 volts and below, and are not tolerant of the 5 volt signals used by older hardware like the Spectrum, so it also necessarily must include level shifting components. All the important Z80 signals are buffered with bidirectional buffers where necessary (including the address bus, so DMA is possible).<br />
<br />
=== Why the Lattice iCE40 ===<br />
<br />
The iCE40 is a straightforward, low-cost FPGA and it's one of the best documented FPGAs that are available. Unfortunately, manufacturers tend to keep their programming bitstreams secret, which is unfortunate, as you are forced to use their (often bloated) IDEs to develop for them. SiliconBlue (which was bought by Lattice) by contrast, fortunately published the programming bitstream for the iCE40 range. The iCE40 range is also quite straightforwad - it literally is just a sea of logic blocks, some synchronous semi dual ported block RAM, and a couple of PLL blocks. There is also quite a capable chip (in the form of the iCE40 HX4K TQ144) that is in a package that can be hand soldered. Another great thing about the iCE40 is that you're not expected to use JTAG to program it - everything's done through SPI, so a cheap and cheerful Adafruit FT232H board can be used as the programmer.<br />
<br />
You can use the Lattice proprietary IDE if you like, but you can also use the open source Icestorm toolkit.<br />
<br />
One thing that Lattice won't tell you about the iCE40 HX4K TQ144 is that really it's an HX8K device in a TQFP 144 package :-) And the open source tools will treat it as an HX8K.<br />
<br />
=== What can you fit in the chip? ===<br />
<br />
My experimentation so far shows that a basic 65C02 'system on a chip' with a memory controller, some hardware for debugging, a 32-bit timer, an SPI interface, a 9600-baud UART and some other small devices only takes a third of the logic resources. You could easily implement something like a RISC V processor on the chip. There is 16kbytes of block RAM, so you could implement something like a ULA Plus with RGB out on the board.<br />
<br />
[[Category:Make a Chip Pro]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=427Main Page2022-06-04T09:15:56Z<p>Winston: /* Project Info */</p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! Currently, Ben Versteeg of [https://bytedelight.com Byte Delight] is building and selling the Spectranet. There is also a Facebook group run by Ben [https://www.facebook.com/groups/317751018885010/ Spectranet Facebook group]. Ben's YouTube channel (linked from his site) also has a bunch of interesting videos, including the pick-and-place assembly machine used to build the boards.<br />
<br />
Additionally you may find stock at [http://www.sellmyretro.com/ RWAP Software] (who also sells other useful items like replacement keyboard membranes), who sold the Spectranets assembled from around 2014 to 2016.<br />
<br />
2020-02-21: By popular demand, project sources etc. are now available on Github: see https://github.com/spectrumero/spectranet .<br />
<br />
'''Latest Spectranet firmware''': R600 (released 30th November 2020)<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Make a Chip Pro]] - FPGA add-on for the Spectrum, like the [[ZX Breakout]] but with more stuff. For the Spectrum's 40th anniversary!<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [https://github.com/spectrumero/spectranet GitHub] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ICE40-notes&diff=423ICE40-notes2022-03-11T14:32:50Z<p>Winston: </p>
<hr />
<div>Some notes on programming the ICE40 and its flash.<br />
<br />
== Adafruit FT232H connections ==<br />
<br />
* D0 ---> SCK<br />
* D1 ---> MOSI<br />
* D2 ---> MISO<br />
* D3 ---> Not connected<br />
* D4 ---> SS<br />
* D5 ---> Not connected<br />
* D6 ---> CDONE<br />
* D7 ---> CRESET<br />
<br />
== Using <code>iceprog</code> ==<br />
<br />
The USB vendor/product string must be specified:<br />
<br />
iceprog -d i:0x0403:0x6014<br />
<br />
Read flash id:<br />
<br />
iceprog -d i:0x0403:0x6014 -t<br />
<br />
Program:<br />
<br />
iceprog -d i:0x0403:0x6014 [filename]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ICE40-notes&diff=422ICE40-notes2022-03-11T14:25:52Z<p>Winston: Created page with "Some notes on programming the ICE40 and its flash. == Adafruit FT232H connections == * D0 ---> SCK * D1 ---> MOSI * D2 ---> MISO * D3 ---> Not connected * D4 ---> SS * D5 ---> Not connected * D6 ---> CDONE * D7 ---> CRESET"</p>
<hr />
<div>Some notes on programming the ICE40 and its flash.<br />
<br />
== Adafruit FT232H connections ==<br />
<br />
* D0 ---> SCK<br />
* D1 ---> MOSI<br />
* D2 ---> MISO<br />
* D3 ---> Not connected<br />
* D4 ---> SS<br />
* D5 ---> Not connected<br />
* D6 ---> CDONE<br />
* D7 ---> CRESET</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=419Main Page2020-11-30T21:09:21Z<p>Winston: </p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! Currently, Ben Versteeg of [https://bytedelight.com Byte Delight] is building and selling the Spectranet. There is also a Facebook group run by Ben [https://www.facebook.com/groups/317751018885010/ Spectranet Facebook group]. Ben's YouTube channel (linked from his site) also has a bunch of interesting videos, including the pick-and-place assembly machine used to build the boards.<br />
<br />
Additionally you may find stock at [http://www.sellmyretro.com/ RWAP Software] (who also sells other useful items like replacement keyboard membranes), who sold the Spectranets assembled from around 2014 to 2016.<br />
<br />
2020-02-21: By popular demand, project sources etc. are now available on Github: see https://github.com/spectrumero/spectranet .<br />
<br />
'''Latest Spectranet firmware''': R600 (released 30th November 2020)<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [https://github.com/spectrumero/spectranet GitHub] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=418Main Page2020-02-22T10:11:16Z<p>Winston: /* Latest News */</p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! Currently, Ben Versteeg of [https://bytedelight.com Byte Delight] is building and selling the Spectranet. There is also a Facebook group run by Ben [https://www.facebook.com/groups/317751018885010/ Spectranet Facebook group]. Ben's YouTube channel (linked from his site) also has a bunch of interesting videos, including the pick-and-place assembly machine used to build the boards.<br />
<br />
Additionally you may find stock at [http://www.sellmyretro.com/ RWAP Software] (who also sells other useful items like replacement keyboard membranes), who sold the Spectranets assembled from around 2014 to 2016.<br />
<br />
2020-02-21: By popular demand, project sources etc. are now available on Github: see https://github.com/spectrumero/spectranet .<br />
<br />
'''Latest Spectranet firmware''': R569 (released 4th November 2013)<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [https://github.com/spectrumero/spectranet GitHub] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=417Main Page2020-02-22T10:06:36Z<p>Winston: </p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! Currently, Ben Versteeg of [https://bytedelight.com Byte Delight] is building and selling the Spectranet. There is also a Facebook group run by Ben [https://www.facebook.com/groups/317751018885010/ Spectranet Facebook group]<br />
<br />
Additionally you may find stock at [http://www.sellmyretro.com/ RWAP Software] (who also sells other useful items like replacement keyboard membranes), who sold the Spectranets assembled from around 2014 to 2016.<br />
<br />
2020-02-21: By popular demand, project sources etc. are now available on Github: see https://github.com/spectrumero/spectranet .<br />
<br />
'''Latest Spectranet firmware''': R569 (released 4th November 2013)<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [https://github.com/spectrumero/spectranet GitHub] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=416Main Page2020-02-22T10:04:00Z<p>Winston: </p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! Currently, Ben Versteeg of [https://bytedelight.com Byte Delight] is building and selling the Spectranet.<br />
<br />
Additionally you may find stock at [http://www.sellmyretro.com/ RWAP Software] (who also sells other useful items like replacement keyboard membranes), who sold the Spectranets assembled from around 2014 to 2016.<br />
<br />
2020-02-21: By popular demand, project sources etc. are now available on Github: see https://github.com/spectrumero/spectranet .<br />
<br />
'''Latest Spectranet firmware''': R569 (released 4th November 2013)<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Spectramin]] - Spectrum 128K AY theremin<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[SpectraDVI]] - A digital video ULA+ add-on for the Spectrum?<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [http://spectrum.alioth.net/svn WebSVN] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=415Main Page2020-02-22T09:58:41Z<p>Winston: </p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! They are sold via [http://www.sellmyretro.com/offer/details/*BRAND_NEW*_Sinclair_ZX_Spectrum_Spectranet_%28Ethernet_add-on%29-2511 RWAP Software] (who also sells other useful items like replacement keyboard membranes). The Spectranet is also available from the RWAP Software stand at retro events.<br />
<br />
2020-02-21: By popular demand, project sources etc. are now available on Github: see https://github.com/spectrumero/spectranet .<br />
<br />
'''Latest Spectranet firmware''': R569 (released 4th November 2013)<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Spectramin]] - Spectrum 128K AY theremin<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[SpectraDVI]] - A digital video ULA+ add-on for the Spectrum?<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [http://spectrum.alioth.net/svn WebSVN] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_Breakout&diff=414ZX Breakout2019-03-25T14:06:39Z<p>Winston: </p>
<hr />
<div>[[Image:Zxbreakout1.jpg|thumb|right|500px|ZX Breakout with XC95144XL]]<br />
<br />
This is a CPLD (complex programmable logic device) breakout board for the Spectrum (including 128K and Amstrad models). The original idea behind this board was to provide a breakout board for the ZX Spectrum bus signals, and also level shifting of all the signals to 3.3v with a second set of breakout pins. This was to provide an interface to chips that are not 5v tolerant, such as all current in-production FPGAs.<br />
<br />
Using a CPLD instead of simple level shifters does two things: it provides the original functionality of a breakout board with a level shifter since a 3.3v CPLD with 5v tolerant IO can be used for this purpose, and for prototyping or making the logic for other things too - in other words, make a versatile breakout board for both the ZX bus and a CPLD.<br />
<br />
Either the Xilinx XC9572XL or the XC95144XL CPLD can be used on this board. To give a rough idea of the logic resources these CPLDs provide, Chris Smith's timing accurate ULA replacement fills an XC95144XL, that's to say this CPLD has a similiar amount of resource to the Spectrum ULA.<br />
<br />
=== Errata ===<br />
Due to a dumb mistake, the ROMCS circuit is incorrect for the black +2 and +3 machines. If you intend to use the ZX Breakout with one of these, a simple workaround is to just not connect pin 4 of the edge connector (top side, 4th pin from the left) or desolder it if you've already connected it. The board will not work at all with a black +2 or +3 unless you do this, even if you're not planning to use ROMCS. It works fine with all other models as-is.<br />
<br />
== The board ==<br />
<br />
[[Image:Zxbreakout.png|thumb|right|500px|ZX Breakout PCB]]<br />
<br />
The PCB features the following:<br />
<br />
* All major ZX bus digital signals routed to the CPLD.<br />
* Header for ZX signals, nearest the Spectrum edge connector.<br />
* 3.3v linear power supply for the CPLD.<br />
* JTAG header for programming the CPLD.<br />
* Ability to control the ROMCS line.<br />
* Clock is inverted (to be in phase with the CPU clock) by a Schmitt-trigger buffer giving sharper rising and falling edges.<br />
* Two headers for CPLD signals - a 40 pin header with 32 CPLD general purpose IOs, and a 10 pin header with 7 general purpose IOs.<br />
* 40 pin header laid out with ground and power pins in the same location as an IDE connector.<br />
* 4 layer PCB with solid ground and power planes for ideal CPLD performance.<br />
<br />
Additionally, the ZX signals and CPLD pin locations are shown in the silk screen, so you know what you're connecting to without having to reach for a datasheet.<br />
<br />
== Pin locations ==<br />
<br />
=== ZX bus to CPLD ===<br />
<br />
ZX bus function to CPLD function block mapping is optimized for the XC9572, being the smallest device with fewest resources. For the '72, the data bus and upper half of the address bus is grouped into function block 1, and the lower half of the address bus and control signals in function block 3. The remaining pins go to the GPIO headers.<br />
<br />
The ZX clock is mapped to a global clock signal, and the reset signal is inverted and buffered and routed to the global system reset pin. A global clock signal is available on the GPIO header.<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"| ZX signal<br />
! CPLD pin<br />
! XC9572 FB<br />
! XC95144 FB<br />
! Comments<br />
|- <br />
|D0||18||1||1||<br />
|- <br />
|D1||20||1||1||<br />
|-<br />
|D2||22||1||1||<br />
|- <br />
|D3||29||1||3||<br />
|-<br />
|D4||30||1||3||<br />
|- <br />
|D5||28||1||3||<br />
|-<br />
|D6||25||1||3||<br />
|- <br />
|D7||17||1||1||<br />
|-<br />
|A0||32||3||3||<br />
|- <br />
|A1||35||3||5||<br />
|-<br />
|A2||37||3||5||<br />
|- <br />
|A3||41||3||5||<br />
|-<br />
|A4||59||3||7||<br />
|- <br />
|A5||58||3||7||<br />
|-<br />
|A6||56||3||7||<br />
|- <br />
|A7||55||3||7||<br />
|-<br />
|A8||40||1||5||<br />
|- <br />
|A9||39||1||5||<br />
|-<br />
|A10||36||1||5||<br />
|- <br />
|A11||33||1||3||<br />
|-<br />
|A12||15||1||1||<br />
|- <br />
|A13||16||1||1||<br />
|-<br />
|A14||13||1||1||<br />
|- <br />
|A15||14||1||1||<br />
|-<br />
|/MREQ||50||3||7||<br />
|- <br />
|/IORQ||52||3||7||<br />
|-<br />
|/RD||53||3||7||<br />
|- <br />
|/WR||54||3||7||<br />
|-<br />
|/M1||60||3||7||<br />
|- <br />
|/INT||42||3||5||<br />
|-<br />
|/NMI||49||3||5||<br />
|-<br />
|CLK||23||1||5||Buffered; CPLD GCK2<br />
|-<br />
|RESET||99||2||3||Buffered; CPLD GSR (active high)<br />
|-<br />
|ROMCS||61||3||7||Only when "Use ROMCS" is jumpered<br />
|-<br />
|}<br />
<br />
=== 40 pin header ===<br />
<br />
The 40 pin header is numbered using the ribbon cable style of numbering. Pin 1 is at the top right hand side of the connector, when looking down at the component side of the PCB, with the ZX edge connector at the bottom (in other words, as shown in the image on this page).<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"| Header pin<br />
! CPLD pin<br />
! XC9572 FB<br />
! XC95144 FB<br />
! Comments<br />
|- <br />
|1||68||4||8||<br />
|- <br />
|2||GND||||||<br />
|-<br />
|3||71||4||8||<br />
|-<br />
|4||70||4||8||<br />
|-<br />
|5||74||4||6||<br />
|-<br />
|6||72||4||8||<br />
|-<br />
|7||77||4||6||<br />
|-<br />
|8||76||4||6||<br />
|-<br />
|9||79||4||6||<br />
|-<br />
|10||78||4||6||<br />
|-<br />
|11||82||4||6||<br />
|-<br />
|12||81||4||6||<br />
|-<br />
|13||86||4||6||<br />
|-<br />
|14||85||4||6||<br />
|-<br />
|15||89||4||4||<br />
|-<br />
|16||87||2||4||<br />
|-<br />
|17||91||2||4||<br />
|-<br />
|18||90||4||4||<br />
|-<br />
|19||GND||||||<br />
|-<br />
|20||3.3v||||||<br />
|-<br />
|21||92||2||4||<br />
|-<br />
|22||GND||||||<br />
|-<br />
|23||93||2||4||<br />
|-<br />
|24||GND||||||<br />
|-<br />
|25||94||2||4||<br />
|-<br />
|26||GND||||||<br />
|-<br />
|27||95||2||4||<br />
|-<br />
|28||96||2||4||<br />
|-<br />
|29||97||2||4||<br />
|-<br />
|30||GND||||||<br />
|-<br />
|31||1||2||2||<br />
|-<br />
|32||3||2||2||GTS1<br />
|-<br />
|33||4||2||2||GTS2<br />
|-<br />
|34||6||2||2||<br />
|-<br />
|35||8||2||2||<br />
|-<br />
|36||9||2||2||<br />
|-<br />
|37||10||2||2||<br />
|-<br />
|38||11||2||1||<br />
|-<br />
|39||12||2||1||<br />
|-<br />
|40||GND||||||<br />
|-<br />
|}<br />
<br />
=== 10 pin header ===<br />
<br />
This header uses ribbon cable numbering, with pin 1 being the top left pin looking down on the PCB, as in the image above.<br />
<br />
Pin 4 is the same as the ROMCS pin on the header next to the edge connector - it's just a straight connection. It is provided as an alternative site to connect a wire to ROMCS. Pin 9 is not connected to the CPLD if the "Use ROMCS" jumper is closed. When this jumper is closed, CPLD pin 61 will go to the transistor controlling the ROMCS line allowing the CPLD to page out the ZX ROM. Pin 10 routes to a global clock pin, it may also be used as general purpose IO.<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"| Header pin<br />
! CPLD pin<br />
! XC9572 FB<br />
! XC95144 FB<br />
! Comments<br />
|- <br />
|1||3.3v||||||<br />
|-<br />
|2||GND||||||<br />
|-<br />
|3||67||4||8||<br />
|-<br />
|4||ROMCS||||<br />
|-<br />
|5||66||4||8||<br />
|-<br />
|6||65||4||8||<br />
|-<br />
|7||64||3||8||<br />
|-<br />
|8||63||3||8||<br />
|-<br />
|9||61||3||7||May be routed to ROMCS<br />
|-<br />
|10||27||1||3||GCK3<br />
|-<br />
|}<br />
<br />
== Xilinx UCF file for pins ==<br />
<br />
Copy and paste this into your UCF text constraints file for the list of pins. Comment out the signals you aren't using with a # in front of that line (ISE will fail at the fitter stage if you have nets defined in your UCF file which don't exist in your design). Signals with "_L" at the end are active low. Note that RESET is active high (it's been inverted). This is generally what you want; the Xilinx library components all have active high reset. The clock is also in phase with the Z80 clock.<br />
<br />
Also note that the pin used to control ROMCS can also be used as a GPIO, depending on the position of the jumper. ROMCS is active low from the point of view of the CPLD.<br />
<br />
This file will also appear in Subversion.<br />
<br />
GPIO pins are not listed in this file since you'll be defining them according to whatever function they may have.<br />
<br />
net A(0) loc=p32;<br />
net A(1) loc=p35;<br />
net A(2) loc=p37;<br />
net A(3) loc=p41;<br />
net A(4) loc=p59;<br />
net A(5) loc=p58;<br />
net A(6) loc=p56;<br />
net A(7) loc=p55;<br />
<br />
net A(8) loc=p40;<br />
net A(9) loc=p39;<br />
net A(10) loc=p36;<br />
net A(11) loc=p33;<br />
net A(12) loc=p15;<br />
net A(13) loc=p16;<br />
net A(14) loc=p13;<br />
net A(15) loc=p14;<br />
<br />
net D(0) loc=p18;<br />
net D(1) loc=p20;<br />
net D(2) loc=p22;<br />
net D(3) loc=p29;<br />
net D(4) loc=p30;<br />
net D(5) loc=p28;<br />
net D(6) loc=p25;<br />
net D(7) loc=p17; <br />
<br />
net MREQ_L loc=p50;<br />
net IORQ_L loc=p52;<br />
net RD_L loc=p53;<br />
net WR_L loc=p54;<br />
net M1_L loc=p60;<br />
net INT_L loc=p42;<br />
net NMI_L loc=p49; <br />
<br />
net CLK loc=p23;<br />
net RESET loc=p99;<br />
<br />
net ROMCS_L loc=p61;<br />
<br />
== Components used ==<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"|Refdes<br />
! Component<br />
! Package<br />
! Mfr.<br />
! Description<br />
! Notes<br />
|- <br />
|U1||P565D2T33||D2PAK3||ON Semi||3.3v LDO regulator||<br />
|-<br />
|U2||74HCT14||SOIC 14||Any||Schmitt trigger inverter, TTL compatible||<br />
|-<br />
|U3||XC9572XL||TQFP 100||Xilinx||CPLD||Use XC95144XL for more logic resources<br />
|-<br />
|C1, C2||150uF||Tant B||Any||Capacitor||<br />
|-<br />
|C3||1uF||1206||Any||Capacitor||<br />
|-<br />
|C4 to C10||0.1uF||0603||Any||Capacitor||<br />
|-<br />
|R1||300R||0603||Any||Resistor||<br />
|-<br />
|Q1||BSS84P||SOT23||Infineon||P channel MOSFET||<br />
|-<br />
|}<br />
<br />
ZX bus edge connector is an open ended 28 position 0.1 inch pitch connector, with position 5 contacts removed and replaced with a plastic key. This connector usually needs to be hand made by cutting down a larger connector (such as an old ISA bus connector).<br />
<br />
40 pin, 10 pin and 60 pin headers are up to the board's user. It's suggested that SIL sockets are used for the headers since this allows wires to be plugged in and connected to a breadboard etc. However, if a ribbon cable is to be used, a PCB to ribbon connector is recommended.<br />
<br />
It is suggested that normal jumper pin headers are used for the jumpers.<br />
<br />
== Projects for the ZX Breakout ==<br />
<br />
* [[ZX SPI]] - An SPI interface for the Spectrum.<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_Breakout&diff=413ZX Breakout2019-03-25T14:05:40Z<p>Winston: </p>
<hr />
<div>[[Image:Zxbreakout1.jpg|thumb|right|510px|ZX Breakout with XC95144XL]]<br />
<br />
This is a CPLD (complex programmable logic device) breakout board for the Spectrum (including 128K and Amstrad models). The original idea behind this board was to provide a breakout board for the ZX Spectrum bus signals, and also level shifting of all the signals to 3.3v with a second set of breakout pins. This was to provide an interface to chips that are not 5v tolerant, such as all current in-production FPGAs.<br />
<br />
Using a CPLD instead of simple level shifters does two things: it provides the original functionality of a breakout board with a level shifter since a 3.3v CPLD with 5v tolerant IO can be used for this purpose, and for prototyping or making the logic for other things too - in other words, make a versatile breakout board for both the ZX bus and a CPLD.<br />
<br />
Either the Xilinx XC9572XL or the XC95144XL CPLD can be used on this board. To give a rough idea of the logic resources these CPLDs provide, Chris Smith's timing accurate ULA replacement fills an XC95144XL, that's to say this CPLD has a similiar amount of resource to the Spectrum ULA.<br />
<br />
=== Errata ===<br />
Due to a dumb mistake, the ROMCS circuit is incorrect for the black +2 and +3 machines. If you intend to use the ZX Breakout with one of these, a simple workaround is to just not connect pin 4 of the edge connector (top side, 4th pin from the left) or desolder it if you've already connected it. The board will not work at all with a black +2 or +3 unless you do this, even if you're not planning to use ROMCS. It works fine with all other models as-is.<br />
<br />
== The board ==<br />
<br />
[[Image:Zxbreakout.png|thumb|right|510px|ZX Breakout PCB]]<br />
<br />
The PCB features the following:<br />
<br />
* All major ZX bus digital signals routed to the CPLD.<br />
* Header for ZX signals, nearest the Spectrum edge connector.<br />
* 3.3v linear power supply for the CPLD.<br />
* JTAG header for programming the CPLD.<br />
* Ability to control the ROMCS line.<br />
* Clock is inverted (to be in phase with the CPU clock) by a Schmitt-trigger buffer giving sharper rising and falling edges.<br />
* Two headers for CPLD signals - a 40 pin header with 32 CPLD general purpose IOs, and a 10 pin header with 7 general purpose IOs.<br />
* 40 pin header laid out with ground and power pins in the same location as an IDE connector.<br />
* 4 layer PCB with solid ground and power planes for ideal CPLD performance.<br />
<br />
Additionally, the ZX signals and CPLD pin locations are shown in the silk screen, so you know what you're connecting to without having to reach for a datasheet.<br />
<br />
== Pin locations ==<br />
<br />
=== ZX bus to CPLD ===<br />
<br />
ZX bus function to CPLD function block mapping is optimized for the XC9572, being the smallest device with fewest resources. For the '72, the data bus and upper half of the address bus is grouped into function block 1, and the lower half of the address bus and control signals in function block 3. The remaining pins go to the GPIO headers.<br />
<br />
The ZX clock is mapped to a global clock signal, and the reset signal is inverted and buffered and routed to the global system reset pin. A global clock signal is available on the GPIO header.<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"| ZX signal<br />
! CPLD pin<br />
! XC9572 FB<br />
! XC95144 FB<br />
! Comments<br />
|- <br />
|D0||18||1||1||<br />
|- <br />
|D1||20||1||1||<br />
|-<br />
|D2||22||1||1||<br />
|- <br />
|D3||29||1||3||<br />
|-<br />
|D4||30||1||3||<br />
|- <br />
|D5||28||1||3||<br />
|-<br />
|D6||25||1||3||<br />
|- <br />
|D7||17||1||1||<br />
|-<br />
|A0||32||3||3||<br />
|- <br />
|A1||35||3||5||<br />
|-<br />
|A2||37||3||5||<br />
|- <br />
|A3||41||3||5||<br />
|-<br />
|A4||59||3||7||<br />
|- <br />
|A5||58||3||7||<br />
|-<br />
|A6||56||3||7||<br />
|- <br />
|A7||55||3||7||<br />
|-<br />
|A8||40||1||5||<br />
|- <br />
|A9||39||1||5||<br />
|-<br />
|A10||36||1||5||<br />
|- <br />
|A11||33||1||3||<br />
|-<br />
|A12||15||1||1||<br />
|- <br />
|A13||16||1||1||<br />
|-<br />
|A14||13||1||1||<br />
|- <br />
|A15||14||1||1||<br />
|-<br />
|/MREQ||50||3||7||<br />
|- <br />
|/IORQ||52||3||7||<br />
|-<br />
|/RD||53||3||7||<br />
|- <br />
|/WR||54||3||7||<br />
|-<br />
|/M1||60||3||7||<br />
|- <br />
|/INT||42||3||5||<br />
|-<br />
|/NMI||49||3||5||<br />
|-<br />
|CLK||23||1||5||Buffered; CPLD GCK2<br />
|-<br />
|RESET||99||2||3||Buffered; CPLD GSR (active high)<br />
|-<br />
|ROMCS||61||3||7||Only when "Use ROMCS" is jumpered<br />
|-<br />
|}<br />
<br />
=== 40 pin header ===<br />
<br />
The 40 pin header is numbered using the ribbon cable style of numbering. Pin 1 is at the top right hand side of the connector, when looking down at the component side of the PCB, with the ZX edge connector at the bottom (in other words, as shown in the image on this page).<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"| Header pin<br />
! CPLD pin<br />
! XC9572 FB<br />
! XC95144 FB<br />
! Comments<br />
|- <br />
|1||68||4||8||<br />
|- <br />
|2||GND||||||<br />
|-<br />
|3||71||4||8||<br />
|-<br />
|4||70||4||8||<br />
|-<br />
|5||74||4||6||<br />
|-<br />
|6||72||4||8||<br />
|-<br />
|7||77||4||6||<br />
|-<br />
|8||76||4||6||<br />
|-<br />
|9||79||4||6||<br />
|-<br />
|10||78||4||6||<br />
|-<br />
|11||82||4||6||<br />
|-<br />
|12||81||4||6||<br />
|-<br />
|13||86||4||6||<br />
|-<br />
|14||85||4||6||<br />
|-<br />
|15||89||4||4||<br />
|-<br />
|16||87||2||4||<br />
|-<br />
|17||91||2||4||<br />
|-<br />
|18||90||4||4||<br />
|-<br />
|19||GND||||||<br />
|-<br />
|20||3.3v||||||<br />
|-<br />
|21||92||2||4||<br />
|-<br />
|22||GND||||||<br />
|-<br />
|23||93||2||4||<br />
|-<br />
|24||GND||||||<br />
|-<br />
|25||94||2||4||<br />
|-<br />
|26||GND||||||<br />
|-<br />
|27||95||2||4||<br />
|-<br />
|28||96||2||4||<br />
|-<br />
|29||97||2||4||<br />
|-<br />
|30||GND||||||<br />
|-<br />
|31||1||2||2||<br />
|-<br />
|32||3||2||2||GTS1<br />
|-<br />
|33||4||2||2||GTS2<br />
|-<br />
|34||6||2||2||<br />
|-<br />
|35||8||2||2||<br />
|-<br />
|36||9||2||2||<br />
|-<br />
|37||10||2||2||<br />
|-<br />
|38||11||2||1||<br />
|-<br />
|39||12||2||1||<br />
|-<br />
|40||GND||||||<br />
|-<br />
|}<br />
<br />
=== 10 pin header ===<br />
<br />
This header uses ribbon cable numbering, with pin 1 being the top left pin looking down on the PCB, as in the image above.<br />
<br />
Pin 4 is the same as the ROMCS pin on the header next to the edge connector - it's just a straight connection. It is provided as an alternative site to connect a wire to ROMCS. Pin 9 is not connected to the CPLD if the "Use ROMCS" jumper is closed. When this jumper is closed, CPLD pin 61 will go to the transistor controlling the ROMCS line allowing the CPLD to page out the ZX ROM. Pin 10 routes to a global clock pin, it may also be used as general purpose IO.<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"| Header pin<br />
! CPLD pin<br />
! XC9572 FB<br />
! XC95144 FB<br />
! Comments<br />
|- <br />
|1||3.3v||||||<br />
|-<br />
|2||GND||||||<br />
|-<br />
|3||67||4||8||<br />
|-<br />
|4||ROMCS||||<br />
|-<br />
|5||66||4||8||<br />
|-<br />
|6||65||4||8||<br />
|-<br />
|7||64||3||8||<br />
|-<br />
|8||63||3||8||<br />
|-<br />
|9||61||3||7||May be routed to ROMCS<br />
|-<br />
|10||27||1||3||GCK3<br />
|-<br />
|}<br />
<br />
== Xilinx UCF file for pins ==<br />
<br />
Copy and paste this into your UCF text constraints file for the list of pins. Comment out the signals you aren't using with a # in front of that line (ISE will fail at the fitter stage if you have nets defined in your UCF file which don't exist in your design). Signals with "_L" at the end are active low. Note that RESET is active high (it's been inverted). This is generally what you want; the Xilinx library components all have active high reset. The clock is also in phase with the Z80 clock.<br />
<br />
Also note that the pin used to control ROMCS can also be used as a GPIO, depending on the position of the jumper. ROMCS is active low from the point of view of the CPLD.<br />
<br />
This file will also appear in Subversion.<br />
<br />
GPIO pins are not listed in this file since you'll be defining them according to whatever function they may have.<br />
<br />
net A(0) loc=p32;<br />
net A(1) loc=p35;<br />
net A(2) loc=p37;<br />
net A(3) loc=p41;<br />
net A(4) loc=p59;<br />
net A(5) loc=p58;<br />
net A(6) loc=p56;<br />
net A(7) loc=p55;<br />
<br />
net A(8) loc=p40;<br />
net A(9) loc=p39;<br />
net A(10) loc=p36;<br />
net A(11) loc=p33;<br />
net A(12) loc=p15;<br />
net A(13) loc=p16;<br />
net A(14) loc=p13;<br />
net A(15) loc=p14;<br />
<br />
net D(0) loc=p18;<br />
net D(1) loc=p20;<br />
net D(2) loc=p22;<br />
net D(3) loc=p29;<br />
net D(4) loc=p30;<br />
net D(5) loc=p28;<br />
net D(6) loc=p25;<br />
net D(7) loc=p17; <br />
<br />
net MREQ_L loc=p50;<br />
net IORQ_L loc=p52;<br />
net RD_L loc=p53;<br />
net WR_L loc=p54;<br />
net M1_L loc=p60;<br />
net INT_L loc=p42;<br />
net NMI_L loc=p49; <br />
<br />
net CLK loc=p23;<br />
net RESET loc=p99;<br />
<br />
net ROMCS_L loc=p61;<br />
<br />
== Components used ==<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"|Refdes<br />
! Component<br />
! Package<br />
! Mfr.<br />
! Description<br />
! Notes<br />
|- <br />
|U1||P565D2T33||D2PAK3||ON Semi||3.3v LDO regulator||<br />
|-<br />
|U2||74HCT14||SOIC 14||Any||Schmitt trigger inverter, TTL compatible||<br />
|-<br />
|U3||XC9572XL||TQFP 100||Xilinx||CPLD||Use XC95144XL for more logic resources<br />
|-<br />
|C1, C2||150uF||Tant B||Any||Capacitor||<br />
|-<br />
|C3||1uF||1206||Any||Capacitor||<br />
|-<br />
|C4 to C10||0.1uF||0603||Any||Capacitor||<br />
|-<br />
|R1||300R||0603||Any||Resistor||<br />
|-<br />
|Q1||BSS84P||SOT23||Infineon||P channel MOSFET||<br />
|-<br />
|}<br />
<br />
ZX bus edge connector is an open ended 28 position 0.1 inch pitch connector, with position 5 contacts removed and replaced with a plastic key. This connector usually needs to be hand made by cutting down a larger connector (such as an old ISA bus connector).<br />
<br />
40 pin, 10 pin and 60 pin headers are up to the board's user. It's suggested that SIL sockets are used for the headers since this allows wires to be plugged in and connected to a breadboard etc. However, if a ribbon cable is to be used, a PCB to ribbon connector is recommended.<br />
<br />
It is suggested that normal jumper pin headers are used for the jumpers.<br />
<br />
== Projects for the ZX Breakout ==<br />
<br />
* [[ZX SPI]] - An SPI interface for the Spectrum.<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=412Main Page2013-11-04T18:23:27Z<p>Winston: </p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! They are sold via [http://www.sellmyretro.com/offer/details/*BRAND_NEW*_Sinclair_ZX_Spectrum_Spectranet_%28Ethernet_add-on%29-2511 RWAP Software] (who also sells other useful items like replacement keyboard membranes). The Spectranet is also available from the RWAP Software stand at retro events.<br />
<br />
WebSVN has been set up so that the Spectranet repository can be browsed and downloaded easily: see http://spectrum.alioth.net/svn .<br />
<br />
'''Latest Spectranet firmware''': R569 (released 4th November 2013)<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Spectramin]] - Spectrum 128K AY theremin<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[SpectraDVI]] - A digital video ULA+ add-on for the Spectrum?<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [http://spectrum.alioth.net/svn WebSVN] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Downloads&diff=411Downloads2013-11-04T18:22:20Z<p>Winston: </p>
<hr />
<div>== Spectranet Downloads ==<br />
<br />
=== PC based tools ===<br />
<br />
* [[TNFS server]] - Share files from your PC, Raspberry Pi, or other device to a ZX Spectrum.<br />
* [[ethup]] - The ethup tool: Allows you to load a Spectrum's memory with arbitrary data via the NMI menu.<br />
<br />
=== ROM images and Spectrum tools ===<br />
<br />
* [[Spectranet ROM images]] - Flash a new ROM.<br />
<br />
=== How to update Spectranet firmware online ===<br />
<br />
The TNFS server at vexed4.alioth.net has the latest firmware. It's very easy to update on your Spectrum over the internet. Enter these commands in ZX BASIC:<br />
<br />
%mount 0,"vexed4.alioth.net"<br />
%load ""<br />
<br />
On the menu, choose option A (Check/Update firmware) and follow the instructions.<br />
<br />
=== z88dk libraries ===<br />
<br />
Libraries for z88dk are available for network sockets, general Spectranet functions plus a small HTTP library. The following link explains more.<br />
<br />
* [[Spectranet z88dk libraries]]<br />
<br />
<br />
[[Category:Spectranet]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Spectranet_z88dk_libraries&diff=410Spectranet z88dk libraries2013-11-04T18:20:36Z<p>Winston: Created page with "The following file contains the Spectranet libraries for the Z88dk. This allows access to most Spectranet functions via C, including a socket library broadly compatible with the ..."</p>
<hr />
<div>The following file contains the Spectranet libraries for the Z88dk. This allows access to most Spectranet functions via C, including a socket library broadly compatible with the BSD socket library you may find on a modern system.<br />
<br />
The zip file contains two directories - lib and include - unpack the ZIP file in the directory where these exist in your Z88dk tree (or alternately, you can unzip the file elsewhere and just copy the files to the right place).<br />
<br />
The "_np" versions of the libraries are for use when you page the Spectranet ROM in and want to have it remain paged - basically, the code in the library doesn't auto page the Spectranet ROM. If you're writing code that doesn't expect to use the ZX ROM (or doesn't expect to use it much) use the _np version of the library. The http library depends on the socket library, so it doesn't need an _np version since this will come from the underlying library.<br />
<br />
The zip file contains the following libraries:<br />
<br />
* libspectranet - Non-socket Spectranet functions (for example, the calls required to write BASIC extensions etc).<br />
* libsocket - The socket library providing UDP and TCP sockets.<br />
* libhttp - A small http library built on top of lib socket<br />
<br />
[http://spectrum.alioth.net/downloads/z88dklibs.zip Click here to download the libraries]<br />
<br />
[[Category:Spectranet]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=409ZX SPI2013-06-25T21:34:39Z<p>Winston: </p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 3.5MHz to 14kHz<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Full duplex<br />
* Four chip selects<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 62 macrocells (fits an XC9572)<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
There's a demonstration of it in action on YouTube here: [https://www.youtube.com/watch?v=ptBa7qrxDao ZX SPI and Nixie display]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6-5 - SPI chip select to use<br />
bit 4 - 1 = use clock divider, 0 = don't use clock divider<br />
bit 3-1 - set clock speed (bit 4 must be set to 1 to use this)<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 3.5MHz, CPOL 0, using chip select 1.<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Busy, 0 = Ready for a new read/write operation<br />
bit 6-5 - SPI chip select in use<br />
bit 4 - 1 = using clock divider, 0 = not using clock divider<br />
bit 3-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI serial clock speed. If bit 4 is set to 0, then the clock divider is bypassed and the 3.5MHz CPU clock is used as the SPI serial clock. Otherwise, if bit 4 is set to 1, the serial clock speed is determined by a simple 8 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. Here's a table of the speeds selectable when bit 4 is set:<br />
<br />
When bit 4 is set to 1:<br />
<br />
Bits 3-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
<br />
=== Chip selects ===<br />
<br />
There are four chip selects, so you can have up to 4 SPI devices. The active chip select is specified by bits 6 and 5 of the control register. The mapping looks like this:<br />
<br />
Bit 6 Bit 5 Chip select<br />
0 0 1<br />
0 1 2<br />
1 0 3<br />
1 1 4<br />
<br />
Chip select pins on the ZX Breakout will be 67, 68, 71 and 74 for chip select 1 to 4 in that order.<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is 1, then it's still busy sending. Once bit 7 goes back low you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
Reads happen simultaneously to writes. SPI devices don't have an explicit RD or WR signal to specify which one is being done. When you write to an SPI device you get a read for free. If you need to read from a device, but it's not expecting to be written to, then write whatever the device's idle state (for example, 0xFF) is when you write to port 0x043B which will initiate the operation. The data sheet for the SPI device should specify what this is. Once the SPI operation is complete, and the 'busy' bit (bit 7 of the control register) has returned to zero, then reading port 0x043B will return whatever the SPI device deposited on the MISO line.<br />
<br />
The same comments about multiple writes in the above section (checking the control register's bit 7) applies to reading too, since they are effectively the same operation.<br />
<br />
=== Speed of INI/OUTI versus SPI operations ===<br />
<br />
The SPI read/write operation starts on the next rising clock edge (don't forget that the edge connector CLK signal is inverted with respect to the clock the CPU sees) after the IO write completes. The I/O operation is performed on the 4th M cycle of an INI or OTI instruction. The fastest possible read and write you will be able to do is something like this:<br />
<br />
ld bc, 0x053B ; B must be 1 greater than I/O port<br />
ld hl, ptr<br />
outi ; write (hl) to port 0x043B<br />
inc b ; SPI write will begin during execution of this instruction<br />
outi<br />
inc b<br />
outi<br />
...<br />
<br />
The SPI operation takes 8 T-states to complete at full speed, since one bit is read/written to MOSI and MISO per T-stat. This starts on the next rising edge of the internal SPI clock, which will be halfway through the first T-state of INC B. Therefore the SPI operation is guaranteed to have completed before the next OUTI writes to the device. The INC B and first 3 M-cycles of OUTI will require 16 T-states to complete, and the IORQ line doesn't go low until the 17th T-state. This will mean that a 1.75MHz serial clock should be usable in the code above. In this case:<br />
<br />
ld bc, 0x043B<br />
out (c), a<br />
out (c), d<br />
out (c), e<br />
<br />
only the 3.5MHz serial clock is fast enough for the SPI operation to complete before the next OUT. The OUT (C), r instruction has 3 M-cycles, each 4 T-states long, so there will be 9 T-states from IORQ going high until the next OUT operation beginning.<br />
<br />
At lower speeds you'll either need to calculate how many T-states it'll take to complete the SPI operation, and see if your code takes longer than this in between subsequent I/O operations. In the case of a slow SPI serial clock, for a machine code program you'll probably need to check the contents of bit 7 of the status register (0x053B) before starting a new I/O operation.<br />
<br />
You can ignore contention - except on a +3 or +2A/B - because the serial clock is directly derived from the CPU clock, and so while the CPU clock is halted during contention periods, then so will the serial clock. However, this is not the case on a +3 or +2A/B since the CPU clock keeps running and contention is achieved by other means. So for these machines you'll need to use uncontended memory if you want your T-state calculations versus SPI operation calculations accurate.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins and the adjacent pins on the top row.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select 1 (active low)<br />
68 Chip select 2 (active low)<br />
71 Chip select 3 (active low)<br />
74 Chip select 4 (active low)<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=408ZX SPI2013-06-20T23:00:46Z<p>Winston: /* The control and status register */</p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 3.5MHz to 14kHz<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Full duplex<br />
* Four chip selects<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 62 macrocells (fits an XC9572)<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6-5 - SPI chip select to use<br />
bit 4 - 1 = use clock divider, 0 = don't use clock divider<br />
bit 3-1 - set clock speed (bit 4 must be set to 1 to use this)<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 3.5MHz, CPOL 0, using chip select 1.<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Busy, 0 = Ready for a new read/write operation<br />
bit 6-5 - SPI chip select in use<br />
bit 4 - 1 = using clock divider, 0 = not using clock divider<br />
bit 3-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI serial clock speed. If bit 4 is set to 0, then the clock divider is bypassed and the 3.5MHz CPU clock is used as the SPI serial clock. Otherwise, if bit 4 is set to 1, the serial clock speed is determined by a simple 8 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. Here's a table of the speeds selectable when bit 4 is set:<br />
<br />
When bit 4 is set to 1:<br />
<br />
Bits 3-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
<br />
=== Chip selects ===<br />
<br />
There are four chip selects, so you can have up to 4 SPI devices. The active chip select is specified by bits 6 and 5 of the control register. The mapping looks like this:<br />
<br />
Bit 6 Bit 5 Chip select<br />
0 0 1<br />
0 1 2<br />
1 0 3<br />
1 1 4<br />
<br />
Chip select pins on the ZX Breakout will be 67, 68, 71 and 74 for chip select 1 to 4 in that order.<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is 1, then it's still busy sending. Once bit 7 goes back low you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
Reads happen simultaneously to writes. SPI devices don't have an explicit RD or WR signal to specify which one is being done. When you write to an SPI device you get a read for free. If you need to read from a device, but it's not expecting to be written to, then write whatever the device's idle state (for example, 0xFF) is when you write to port 0x043B which will initiate the operation. The data sheet for the SPI device should specify what this is. Once the SPI operation is complete, and the 'busy' bit (bit 7 of the control register) has returned to zero, then reading port 0x043B will return whatever the SPI device deposited on the MISO line.<br />
<br />
The same comments about multiple writes in the above section (checking the control register's bit 7) applies to reading too, since they are effectively the same operation.<br />
<br />
=== Speed of INI/OUTI versus SPI operations ===<br />
<br />
The SPI read/write operation starts on the next rising clock edge (don't forget that the edge connector CLK signal is inverted with respect to the clock the CPU sees) after the IO write completes. The I/O operation is performed on the 4th M cycle of an INI or OTI instruction. The fastest possible read and write you will be able to do is something like this:<br />
<br />
ld bc, 0x053B ; B must be 1 greater than I/O port<br />
ld hl, ptr<br />
outi ; write (hl) to port 0x043B<br />
inc b ; SPI write will begin during execution of this instruction<br />
outi<br />
inc b<br />
outi<br />
...<br />
<br />
The SPI operation takes 8 T-states to complete at full speed, since one bit is read/written to MOSI and MISO per T-stat. This starts on the next rising edge of the internal SPI clock, which will be halfway through the first T-state of INC B. Therefore the SPI operation is guaranteed to have completed before the next OUTI writes to the device. The INC B and first 3 M-cycles of OUTI will require 16 T-states to complete, and the IORQ line doesn't go low until the 17th T-state. This will mean that a 1.75MHz serial clock should be usable in the code above. In this case:<br />
<br />
ld bc, 0x043B<br />
out (c), a<br />
out (c), d<br />
out (c), e<br />
<br />
only the 3.5MHz serial clock is fast enough for the SPI operation to complete before the next OUT. The OUT (C), r instruction has 3 M-cycles, each 4 T-states long, so there will be 9 T-states from IORQ going high until the next OUT operation beginning.<br />
<br />
At lower speeds you'll either need to calculate how many T-states it'll take to complete the SPI operation, and see if your code takes longer than this in between subsequent I/O operations. In the case of a slow SPI serial clock, for a machine code program you'll probably need to check the contents of bit 7 of the status register (0x053B) before starting a new I/O operation.<br />
<br />
You can ignore contention - except on a +3 or +2A/B - because the serial clock is directly derived from the CPU clock, and so while the CPU clock is halted during contention periods, then so will the serial clock. However, this is not the case on a +3 or +2A/B since the CPU clock keeps running and contention is achieved by other means. So for these machines you'll need to use uncontended memory if you want your T-state calculations versus SPI operation calculations accurate.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins and the adjacent pins on the top row.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select 1 (active low)<br />
68 Chip select 2 (active low)<br />
71 Chip select 3 (active low)<br />
74 Chip select 4 (active low)<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=407ZX SPI2013-06-20T23:00:13Z<p>Winston: /* The control and status register */</p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 3.5MHz to 14kHz<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Full duplex<br />
* Four chip selects<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 62 macrocells (fits an XC9572)<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6-5 - SPI chip select to use<br />
bit 4 - 1 = use clock divider, 0 = don't use clock divider<br />
bit 3-1 - set clock speed<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 3.5MHz, CPOL 0, using chip select 1.<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Busy, 0 = Ready for a new read/write operation<br />
bit 6-5 - SPI chip select in use<br />
bit 4 - 1 = using clock divider, 0 = not using clock divider<br />
bit 3-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI serial clock speed. If bit 4 is set to 0, then the clock divider is bypassed and the 3.5MHz CPU clock is used as the SPI serial clock. Otherwise, if bit 4 is set to 1, the serial clock speed is determined by a simple 8 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. Here's a table of the speeds selectable when bit 4 is set:<br />
<br />
When bit 4 is set to 1:<br />
<br />
Bits 3-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
<br />
=== Chip selects ===<br />
<br />
There are four chip selects, so you can have up to 4 SPI devices. The active chip select is specified by bits 6 and 5 of the control register. The mapping looks like this:<br />
<br />
Bit 6 Bit 5 Chip select<br />
0 0 1<br />
0 1 2<br />
1 0 3<br />
1 1 4<br />
<br />
Chip select pins on the ZX Breakout will be 67, 68, 71 and 74 for chip select 1 to 4 in that order.<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is 1, then it's still busy sending. Once bit 7 goes back low you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
Reads happen simultaneously to writes. SPI devices don't have an explicit RD or WR signal to specify which one is being done. When you write to an SPI device you get a read for free. If you need to read from a device, but it's not expecting to be written to, then write whatever the device's idle state (for example, 0xFF) is when you write to port 0x043B which will initiate the operation. The data sheet for the SPI device should specify what this is. Once the SPI operation is complete, and the 'busy' bit (bit 7 of the control register) has returned to zero, then reading port 0x043B will return whatever the SPI device deposited on the MISO line.<br />
<br />
The same comments about multiple writes in the above section (checking the control register's bit 7) applies to reading too, since they are effectively the same operation.<br />
<br />
=== Speed of INI/OUTI versus SPI operations ===<br />
<br />
The SPI read/write operation starts on the next rising clock edge (don't forget that the edge connector CLK signal is inverted with respect to the clock the CPU sees) after the IO write completes. The I/O operation is performed on the 4th M cycle of an INI or OTI instruction. The fastest possible read and write you will be able to do is something like this:<br />
<br />
ld bc, 0x053B ; B must be 1 greater than I/O port<br />
ld hl, ptr<br />
outi ; write (hl) to port 0x043B<br />
inc b ; SPI write will begin during execution of this instruction<br />
outi<br />
inc b<br />
outi<br />
...<br />
<br />
The SPI operation takes 8 T-states to complete at full speed, since one bit is read/written to MOSI and MISO per T-stat. This starts on the next rising edge of the internal SPI clock, which will be halfway through the first T-state of INC B. Therefore the SPI operation is guaranteed to have completed before the next OUTI writes to the device. The INC B and first 3 M-cycles of OUTI will require 16 T-states to complete, and the IORQ line doesn't go low until the 17th T-state. This will mean that a 1.75MHz serial clock should be usable in the code above. In this case:<br />
<br />
ld bc, 0x043B<br />
out (c), a<br />
out (c), d<br />
out (c), e<br />
<br />
only the 3.5MHz serial clock is fast enough for the SPI operation to complete before the next OUT. The OUT (C), r instruction has 3 M-cycles, each 4 T-states long, so there will be 9 T-states from IORQ going high until the next OUT operation beginning.<br />
<br />
At lower speeds you'll either need to calculate how many T-states it'll take to complete the SPI operation, and see if your code takes longer than this in between subsequent I/O operations. In the case of a slow SPI serial clock, for a machine code program you'll probably need to check the contents of bit 7 of the status register (0x053B) before starting a new I/O operation.<br />
<br />
You can ignore contention - except on a +3 or +2A/B - because the serial clock is directly derived from the CPU clock, and so while the CPU clock is halted during contention periods, then so will the serial clock. However, this is not the case on a +3 or +2A/B since the CPU clock keeps running and contention is achieved by other means. So for these machines you'll need to use uncontended memory if you want your T-state calculations versus SPI operation calculations accurate.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins and the adjacent pins on the top row.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select 1 (active low)<br />
68 Chip select 2 (active low)<br />
71 Chip select 3 (active low)<br />
74 Chip select 4 (active low)<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=406ZX SPI2013-06-20T20:07:59Z<p>Winston: /* Speed of INI/OUTI versus SPI operations */</p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 3.5MHz to 14kHz<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Full duplex<br />
* Four chip selects<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 62 macrocells (fits an XC9572)<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6-5 - SPI chip select to use<br />
bit 4 - 1 = use clock divider, 0 = don't use clock divider<br />
bit 3-1 - set clock speed<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 1.75MHz, CPOL 0, using chip select 1.<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Busy, 0 = Ready for a new read/write operation<br />
bit 6-5 - SPI chip select in use<br />
bit 4 - 1 = using clock divider, 0 = not using clock divider<br />
bit 3-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI serial clock speed. If bit 4 is set to 0, then the clock divider is bypassed and the 3.5MHz CPU clock is used as the SPI serial clock. Otherwise, if bit 4 is set to 1, the serial clock speed is determined by a simple 8 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. Here's a table of the speeds selectable when bit 4 is set:<br />
<br />
When bit 4 is set to 1:<br />
<br />
Bits 3-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
<br />
=== Chip selects ===<br />
<br />
There are four chip selects, so you can have up to 4 SPI devices. The active chip select is specified by bits 6 and 5 of the control register. The mapping looks like this:<br />
<br />
Bit 6 Bit 5 Chip select<br />
0 0 1<br />
0 1 2<br />
1 0 3<br />
1 1 4<br />
<br />
Chip select pins on the ZX Breakout will be 67, 68, 71 and 74 for chip select 1 to 4 in that order.<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is 1, then it's still busy sending. Once bit 7 goes back low you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
Reads happen simultaneously to writes. SPI devices don't have an explicit RD or WR signal to specify which one is being done. When you write to an SPI device you get a read for free. If you need to read from a device, but it's not expecting to be written to, then write whatever the device's idle state (for example, 0xFF) is when you write to port 0x043B which will initiate the operation. The data sheet for the SPI device should specify what this is. Once the SPI operation is complete, and the 'busy' bit (bit 7 of the control register) has returned to zero, then reading port 0x043B will return whatever the SPI device deposited on the MISO line.<br />
<br />
The same comments about multiple writes in the above section (checking the control register's bit 7) applies to reading too, since they are effectively the same operation.<br />
<br />
=== Speed of INI/OUTI versus SPI operations ===<br />
<br />
The SPI read/write operation starts on the next rising clock edge (don't forget that the edge connector CLK signal is inverted with respect to the clock the CPU sees) after the IO write completes. The I/O operation is performed on the 4th M cycle of an INI or OTI instruction. The fastest possible read and write you will be able to do is something like this:<br />
<br />
ld bc, 0x053B ; B must be 1 greater than I/O port<br />
ld hl, ptr<br />
outi ; write (hl) to port 0x043B<br />
inc b ; SPI write will begin during execution of this instruction<br />
outi<br />
inc b<br />
outi<br />
...<br />
<br />
The SPI operation takes 8 T-states to complete at full speed, since one bit is read/written to MOSI and MISO per T-stat. This starts on the next rising edge of the internal SPI clock, which will be halfway through the first T-state of INC B. Therefore the SPI operation is guaranteed to have completed before the next OUTI writes to the device. The INC B and first 3 M-cycles of OUTI will require 16 T-states to complete, and the IORQ line doesn't go low until the 17th T-state. This will mean that a 1.75MHz serial clock should be usable in the code above. In this case:<br />
<br />
ld bc, 0x043B<br />
out (c), a<br />
out (c), d<br />
out (c), e<br />
<br />
only the 3.5MHz serial clock is fast enough for the SPI operation to complete before the next OUT. The OUT (C), r instruction has 3 M-cycles, each 4 T-states long, so there will be 9 T-states from IORQ going high until the next OUT operation beginning.<br />
<br />
At lower speeds you'll either need to calculate how many T-states it'll take to complete the SPI operation, and see if your code takes longer than this in between subsequent I/O operations. In the case of a slow SPI serial clock, for a machine code program you'll probably need to check the contents of bit 7 of the status register (0x053B) before starting a new I/O operation.<br />
<br />
You can ignore contention - except on a +3 or +2A/B - because the serial clock is directly derived from the CPU clock, and so while the CPU clock is halted during contention periods, then so will the serial clock. However, this is not the case on a +3 or +2A/B since the CPU clock keeps running and contention is achieved by other means. So for these machines you'll need to use uncontended memory if you want your T-state calculations versus SPI operation calculations accurate.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins and the adjacent pins on the top row.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select 1 (active low)<br />
68 Chip select 2 (active low)<br />
71 Chip select 3 (active low)<br />
74 Chip select 4 (active low)<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=405ZX SPI2013-06-20T20:03:04Z<p>Winston: /* Setting SPI clock speed */</p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 3.5MHz to 14kHz<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Full duplex<br />
* Four chip selects<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 62 macrocells (fits an XC9572)<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6-5 - SPI chip select to use<br />
bit 4 - 1 = use clock divider, 0 = don't use clock divider<br />
bit 3-1 - set clock speed<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 1.75MHz, CPOL 0, using chip select 1.<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Busy, 0 = Ready for a new read/write operation<br />
bit 6-5 - SPI chip select in use<br />
bit 4 - 1 = using clock divider, 0 = not using clock divider<br />
bit 3-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI serial clock speed. If bit 4 is set to 0, then the clock divider is bypassed and the 3.5MHz CPU clock is used as the SPI serial clock. Otherwise, if bit 4 is set to 1, the serial clock speed is determined by a simple 8 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. Here's a table of the speeds selectable when bit 4 is set:<br />
<br />
When bit 4 is set to 1:<br />
<br />
Bits 3-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
<br />
=== Chip selects ===<br />
<br />
There are four chip selects, so you can have up to 4 SPI devices. The active chip select is specified by bits 6 and 5 of the control register. The mapping looks like this:<br />
<br />
Bit 6 Bit 5 Chip select<br />
0 0 1<br />
0 1 2<br />
1 0 3<br />
1 1 4<br />
<br />
Chip select pins on the ZX Breakout will be 67, 68, 71 and 74 for chip select 1 to 4 in that order.<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is 1, then it's still busy sending. Once bit 7 goes back low you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
Reads happen simultaneously to writes. SPI devices don't have an explicit RD or WR signal to specify which one is being done. When you write to an SPI device you get a read for free. If you need to read from a device, but it's not expecting to be written to, then write whatever the device's idle state (for example, 0xFF) is when you write to port 0x043B which will initiate the operation. The data sheet for the SPI device should specify what this is. Once the SPI operation is complete, and the 'busy' bit (bit 7 of the control register) has returned to zero, then reading port 0x043B will return whatever the SPI device deposited on the MISO line.<br />
<br />
The same comments about multiple writes in the above section (checking the control register's bit 7) applies to reading too, since they are effectively the same operation.<br />
<br />
=== Speed of INI/OUTI versus SPI operations ===<br />
<br />
The SPI read/write operation starts on the next rising clock edge (don't forget that the edge connector CLK signal is inverted with respect to the clock the CPU sees) after the IO write completes. The I/O operation is performed on the 4th M cycle of an INI or OTI instruction. The fastest possible read and write you will be able to do is something like this:<br />
<br />
ld bc, 0x053B ; B must be 1 greater than I/O port<br />
ld hl, ptr<br />
outi ; write (hl) to port 0x043B<br />
inc b ; SPI write will begin during execution of this instruction<br />
outi<br />
inc b<br />
outi<br />
...<br />
<br />
The SPI operation takes 8 T-states to complete at full speed, since one bit is read/written to MOSI and MISO per T-stat. This starts on the next rising edge of the internal SPI clock, which will be halfway through the first T-state of INC B. Therefore the SPI operation is guaranteed to have completed before the next OUTI writes to the device. The INC B and first 3 M-cycles of OUTI will require 16 T-states to complete, and the IORQ line doesn't go low until the 17th T-state. This will mean that a 1.75MHz serial clock should be usable in the code above. In this case:<br />
<br />
ld bc, 0x043B<br />
out (c), a<br />
out (c), d<br />
out (c), e<br />
<br />
only the 3.5MHz serial clock is fast enough for the SPI operation to complete before the next OUT. The OUT (C), r instruction has 3 M-cycles, each 4 T-states long, so there will be 9 T-states from IORQ going high until the next OUT operation beginning.<br />
<br />
At lower speeds you'll either need to calculate how many T-states it'll take to complete the SPI operation, and see if your code takes longer than this in between subsequent I/O operations. In the case of a slow SPI serial clock, for a machine code program you'll probably need to check the contents of bit 7 of the status register (0x053B) before starting a new I/O operation.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins and the adjacent pins on the top row.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select 1 (active low)<br />
68 Chip select 2 (active low)<br />
71 Chip select 3 (active low)<br />
74 Chip select 4 (active low)<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=404ZX SPI2013-06-20T20:02:57Z<p>Winston: /* Setting SPI clock speed */</p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 3.5MHz to 14kHz<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Full duplex<br />
* Four chip selects<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 62 macrocells (fits an XC9572)<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6-5 - SPI chip select to use<br />
bit 4 - 1 = use clock divider, 0 = don't use clock divider<br />
bit 3-1 - set clock speed<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 1.75MHz, CPOL 0, using chip select 1.<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Busy, 0 = Ready for a new read/write operation<br />
bit 6-5 - SPI chip select in use<br />
bit 4 - 1 = using clock divider, 0 = not using clock divider<br />
bit 3-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI serial clock speed. If bit 4 is set to 0, then the clock divider is bypassed and the 3.5MHz CPU clock is used as the SPI serial clock. Otherwise, if bit 4 is set to 1, the serial clock speed is determined by a simple 8 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. Here's a table of the speeds selectable when bit 4 is set:<br />
<br />
When bit 4 is set to 1:<br />
<br />
Bits 3-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
<br />
=== Chip selects ===<br />
<br />
There are four chip selects, so you can have up to 4 SPI devices. The active chip select is specified by bits 6 and 5 of the control register. The mapping looks like this:<br />
<br />
Bit 6 Bit 5 Chip select<br />
0 0 1<br />
0 1 2<br />
1 0 3<br />
1 1 4<br />
<br />
Chip select pins on the ZX Breakout will be 67, 68, 71 and 74 for chip select 1 to 4 in that order.<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is 1, then it's still busy sending. Once bit 7 goes back low you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
Reads happen simultaneously to writes. SPI devices don't have an explicit RD or WR signal to specify which one is being done. When you write to an SPI device you get a read for free. If you need to read from a device, but it's not expecting to be written to, then write whatever the device's idle state (for example, 0xFF) is when you write to port 0x043B which will initiate the operation. The data sheet for the SPI device should specify what this is. Once the SPI operation is complete, and the 'busy' bit (bit 7 of the control register) has returned to zero, then reading port 0x043B will return whatever the SPI device deposited on the MISO line.<br />
<br />
The same comments about multiple writes in the above section (checking the control register's bit 7) applies to reading too, since they are effectively the same operation.<br />
<br />
=== Speed of INI/OUTI versus SPI operations ===<br />
<br />
The SPI read/write operation starts on the next rising clock edge (don't forget that the edge connector CLK signal is inverted with respect to the clock the CPU sees) after the IO write completes. The I/O operation is performed on the 4th M cycle of an INI or OTI instruction. The fastest possible read and write you will be able to do is something like this:<br />
<br />
ld bc, 0x053B ; B must be 1 greater than I/O port<br />
ld hl, ptr<br />
outi ; write (hl) to port 0x043B<br />
inc b ; SPI write will begin during execution of this instruction<br />
outi<br />
inc b<br />
outi<br />
...<br />
<br />
The SPI operation takes 8 T-states to complete at full speed, since one bit is read/written to MOSI and MISO per T-stat. This starts on the next rising edge of the internal SPI clock, which will be halfway through the first T-state of INC B. Therefore the SPI operation is guaranteed to have completed before the next OUTI writes to the device. The INC B and first 3 M-cycles of OUTI will require 16 T-states to complete, and the IORQ line doesn't go low until the 17th T-state. This will mean that a 1.75MHz serial clock should be usable in the code above. In this case:<br />
<br />
ld bc, 0x043B<br />
out (c), a<br />
out (c), d<br />
out (c), e<br />
<br />
only the 3.5MHz serial clock is fast enough for the SPI operation to complete before the next OUT. The OUT (C), r instruction has 3 M-cycles, each 4 T-states long, so there will be 9 T-states from IORQ going high until the next OUT operation beginning.<br />
<br />
At lower speeds you'll either need to calculate how many T-states it'll take to complete the SPI operation, and see if your code takes longer than this in between subsequent I/O operations. In the case of a slow SPI serial clock, for a machine code program you'll probably need to check the contents of bit 7 of the status register (0x053B) before starting a new I/O operation.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins and the adjacent pins on the top row.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select 1 (active low)<br />
68 Chip select 2 (active low)<br />
71 Chip select 3 (active low)<br />
74 Chip select 4 (active low)<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=403ZX SPI2013-06-20T20:02:29Z<p>Winston: </p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 3.5MHz to 14kHz<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Full duplex<br />
* Four chip selects<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 62 macrocells (fits an XC9572)<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6-5 - SPI chip select to use<br />
bit 4 - 1 = use clock divider, 0 = don't use clock divider<br />
bit 3-1 - set clock speed<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 1.75MHz, CPOL 0, using chip select 1.<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Busy, 0 = Ready for a new read/write operation<br />
bit 6-5 - SPI chip select in use<br />
bit 4 - 1 = using clock divider, 0 = not using clock divider<br />
bit 3-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI serial clock speed. If bit 4 is set to 0, then the clock divider is bypassed and the 3.5MHz CPU clock is used as the SPI serial clock. Otherwise, if bit 4 is set to 1, the serial clock speed is determined by a simple 8 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. Here's a table of the speeds selectable when bit 4 is set:<br />
<br />
Bits 3-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
<br />
=== Chip selects ===<br />
<br />
There are four chip selects, so you can have up to 4 SPI devices. The active chip select is specified by bits 6 and 5 of the control register. The mapping looks like this:<br />
<br />
Bit 6 Bit 5 Chip select<br />
0 0 1<br />
0 1 2<br />
1 0 3<br />
1 1 4<br />
<br />
Chip select pins on the ZX Breakout will be 67, 68, 71 and 74 for chip select 1 to 4 in that order.<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is 1, then it's still busy sending. Once bit 7 goes back low you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
Reads happen simultaneously to writes. SPI devices don't have an explicit RD or WR signal to specify which one is being done. When you write to an SPI device you get a read for free. If you need to read from a device, but it's not expecting to be written to, then write whatever the device's idle state (for example, 0xFF) is when you write to port 0x043B which will initiate the operation. The data sheet for the SPI device should specify what this is. Once the SPI operation is complete, and the 'busy' bit (bit 7 of the control register) has returned to zero, then reading port 0x043B will return whatever the SPI device deposited on the MISO line.<br />
<br />
The same comments about multiple writes in the above section (checking the control register's bit 7) applies to reading too, since they are effectively the same operation.<br />
<br />
=== Speed of INI/OUTI versus SPI operations ===<br />
<br />
The SPI read/write operation starts on the next rising clock edge (don't forget that the edge connector CLK signal is inverted with respect to the clock the CPU sees) after the IO write completes. The I/O operation is performed on the 4th M cycle of an INI or OTI instruction. The fastest possible read and write you will be able to do is something like this:<br />
<br />
ld bc, 0x053B ; B must be 1 greater than I/O port<br />
ld hl, ptr<br />
outi ; write (hl) to port 0x043B<br />
inc b ; SPI write will begin during execution of this instruction<br />
outi<br />
inc b<br />
outi<br />
...<br />
<br />
The SPI operation takes 8 T-states to complete at full speed, since one bit is read/written to MOSI and MISO per T-stat. This starts on the next rising edge of the internal SPI clock, which will be halfway through the first T-state of INC B. Therefore the SPI operation is guaranteed to have completed before the next OUTI writes to the device. The INC B and first 3 M-cycles of OUTI will require 16 T-states to complete, and the IORQ line doesn't go low until the 17th T-state. This will mean that a 1.75MHz serial clock should be usable in the code above. In this case:<br />
<br />
ld bc, 0x043B<br />
out (c), a<br />
out (c), d<br />
out (c), e<br />
<br />
only the 3.5MHz serial clock is fast enough for the SPI operation to complete before the next OUT. The OUT (C), r instruction has 3 M-cycles, each 4 T-states long, so there will be 9 T-states from IORQ going high until the next OUT operation beginning.<br />
<br />
At lower speeds you'll either need to calculate how many T-states it'll take to complete the SPI operation, and see if your code takes longer than this in between subsequent I/O operations. In the case of a slow SPI serial clock, for a machine code program you'll probably need to check the contents of bit 7 of the status register (0x053B) before starting a new I/O operation.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins and the adjacent pins on the top row.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select 1 (active low)<br />
68 Chip select 2 (active low)<br />
71 Chip select 3 (active low)<br />
74 Chip select 4 (active low)<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=402ZX SPI2013-06-20T19:41:43Z<p>Winston: </p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 3.5MHz to 14kHz<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Full duplex<br />
* Four chip selects<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 62 macrocells (fits an XC9572)<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6-5 - SPI chip select to use<br />
bit 4 - 1 = use clock divider, 0 = don't use clock divider<br />
bit 3-1 - set clock speed<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 1.75MHz, CPOL 0, using chip select 1.<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Busy, 0 = Ready for a new read/write operation<br />
bit 6-5 - SPI chip select in use<br />
bit 4 - 1 = using clock divider, 0 = not using clock divider<br />
bit 3-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI serial clock speed. If bit 4 is set to 0, then the clock divider is bypassed and the 3.5MHz CPU clock is used as the SPI serial clock. Otherwise, if bit 4 is set to 1, the serial clock speed is determined by a simple 8 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. Here's a table of the speeds selectable when bit 4 is set:<br />
<br />
Bits 3-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
<br />
=== Chip selects ===<br />
<br />
There are four chip selects, so you can have up to 4 SPI devices. The active chip select is specified by bits 6 and 5 of the control register. The mapping looks like this:<br />
<br />
Bit 6 Bit 5 Chip select<br />
0 0 1<br />
0 1 2<br />
1 0 3<br />
1 1 4<br />
<br />
Chip select pins on the ZX Breakout will be 67, 68, 71 and 74 for chip select 1 to 4 in that order.<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is 1, then it's still busy sending. Once bit 7 goes back low you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
Reads happen simultaneously to writes. SPI devices don't have an explicit RD or WR signal to specify which one is being done. When you write to an SPI device you get a read for free. If you need to read from a device, but it's not expecting to be written to, then write whatever the device's idle state (for example, 0xFF) is when you write to port 0x043B which will initiate the operation. The data sheet for the SPI device should specify what this is. Once the SPI operation is complete, and the 'busy' bit (bit 7 of the control register) has returned to zero, then reading port 0x043B will return whatever the SPI device deposited on the MISO line.<br />
<br />
The same comments about multiple writes in the above section (checking the control register's bit 7) applies to reading too, since they are effectively the same operation.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins and the adjacent pins on the top row.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select 1 (active low)<br />
68 Chip select 2 (active low)<br />
71 Chip select 3 (active low)<br />
74 Chip select 4 (active low)<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=401ZX SPI2013-06-19T21:16:59Z<p>Winston: /* The control and status register */</p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 1.75MHz to some absurdly low frequency (up to 16 stages of division, that would make 26 hertz!)<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Full duplex<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 70 macrocells (fits an XC9572)<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6-5 - SPI chip select to use<br />
bit 4-1 - set clock speed<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 1.75MHz, CPOL 0, using chip select 1.<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Busy, 0 = Ready for a new read/write operation<br />
bit 6-5 - SPI chip select in use<br />
bit 4-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI clock speed. The clock speed is determined by a simple 16 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. So to determine the amount that the 1.75MHz clock is divided by, take the value (0 to 15) and raise to the power of two. Here is a table of the most useful clock speeds:<br />
<br />
Bits 4-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
8 7kHz<br />
9 3.5kHz<br />
<br />
The ludicrously low speeds when the divider is set from 10 to 15 may be helpful while debugging, but probably not for actually running an SPI device!<br />
<br />
=== Chip selects ===<br />
<br />
There are four chip selects, so you can have up to 4 SPI devices. The active chip select is specified by bits 6 and 5 of the control register. The mapping looks like this:<br />
<br />
Bit 6 Bit 5 Chip select<br />
0 0 1<br />
0 1 2<br />
1 0 3<br />
1 1 4<br />
<br />
Chip select pins on the ZX Breakout will be 67, 68, 71 and 74 for chip select 1 to 4 in that order.<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is 1, then it's still busy sending. Once bit 7 goes back low you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
Reads happen simultaneously to writes. SPI devices don't have an explicit RD or WR signal to specify which one is being done. When you write to an SPI device you get a read for free. If you need to read from a device, but it's not expecting to be written to, then write whatever the device's idle state (for example, 0xFF) is when you write to port 0x043B which will initiate the operation. The data sheet for the SPI device should specify what this is. Once the SPI operation is complete, and the 'busy' bit (bit 7 of the control register) has returned to zero, then reading port 0x043B will return whatever the SPI device deposited on the MISO line.<br />
<br />
The same comments about multiple writes in the above section (checking the control register's bit 7) applies to reading too, since they are effectively the same operation.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins and the adjacent pins on the top row.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select 1 (active low)<br />
68 Chip select 2 (active low)<br />
71 Chip select 3 (active low)<br />
74 Chip select 4 (active low)<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=400ZX SPI2013-06-19T21:16:43Z<p>Winston: /* The control and status register */</p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 1.75MHz to some absurdly low frequency (up to 16 stages of division, that would make 26 hertz!)<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Full duplex<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 70 macrocells (fits an XC9572)<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6-5 - SPI chip select to use<br />
bit 4-1 - set clock speed<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 1.75MHz, CPOL 0, using chip select 1.<br />
<br />
If bit 5 is set to 1 when writing to the register, all other bits are ignored. This is to save the trouble of having to read the port back, merge in bit 5 and send it again (or storing the settings in memory).<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Busy, 0 = Ready for a new read/write operation<br />
bit 6-5 - SPI chip select in use<br />
bit 4-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI clock speed. The clock speed is determined by a simple 16 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. So to determine the amount that the 1.75MHz clock is divided by, take the value (0 to 15) and raise to the power of two. Here is a table of the most useful clock speeds:<br />
<br />
Bits 4-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
8 7kHz<br />
9 3.5kHz<br />
<br />
The ludicrously low speeds when the divider is set from 10 to 15 may be helpful while debugging, but probably not for actually running an SPI device!<br />
<br />
=== Chip selects ===<br />
<br />
There are four chip selects, so you can have up to 4 SPI devices. The active chip select is specified by bits 6 and 5 of the control register. The mapping looks like this:<br />
<br />
Bit 6 Bit 5 Chip select<br />
0 0 1<br />
0 1 2<br />
1 0 3<br />
1 1 4<br />
<br />
Chip select pins on the ZX Breakout will be 67, 68, 71 and 74 for chip select 1 to 4 in that order.<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is 1, then it's still busy sending. Once bit 7 goes back low you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
Reads happen simultaneously to writes. SPI devices don't have an explicit RD or WR signal to specify which one is being done. When you write to an SPI device you get a read for free. If you need to read from a device, but it's not expecting to be written to, then write whatever the device's idle state (for example, 0xFF) is when you write to port 0x043B which will initiate the operation. The data sheet for the SPI device should specify what this is. Once the SPI operation is complete, and the 'busy' bit (bit 7 of the control register) has returned to zero, then reading port 0x043B will return whatever the SPI device deposited on the MISO line.<br />
<br />
The same comments about multiple writes in the above section (checking the control register's bit 7) applies to reading too, since they are effectively the same operation.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins and the adjacent pins on the top row.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select 1 (active low)<br />
68 Chip select 2 (active low)<br />
71 Chip select 3 (active low)<br />
74 Chip select 4 (active low)<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=399ZX SPI2013-06-19T21:16:19Z<p>Winston: /* The control and status register */</p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 1.75MHz to some absurdly low frequency (up to 16 stages of division, that would make 26 hertz!)<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Full duplex<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 70 macrocells (fits an XC9572)<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6-5 - SPI chip select to use<br />
bit 4-1 - set clock speed<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 1.75MHz, CPOL 0.<br />
<br />
If bit 5 is set to 1 when writing to the register, all other bits are ignored. This is to save the trouble of having to read the port back, merge in bit 5 and send it again (or storing the settings in memory).<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Busy, 0 = Ready for a new read/write operation<br />
bit 6-5 - SPI chip select in use<br />
bit 4-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI clock speed. The clock speed is determined by a simple 16 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. So to determine the amount that the 1.75MHz clock is divided by, take the value (0 to 15) and raise to the power of two. Here is a table of the most useful clock speeds:<br />
<br />
Bits 4-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
8 7kHz<br />
9 3.5kHz<br />
<br />
The ludicrously low speeds when the divider is set from 10 to 15 may be helpful while debugging, but probably not for actually running an SPI device!<br />
<br />
=== Chip selects ===<br />
<br />
There are four chip selects, so you can have up to 4 SPI devices. The active chip select is specified by bits 6 and 5 of the control register. The mapping looks like this:<br />
<br />
Bit 6 Bit 5 Chip select<br />
0 0 1<br />
0 1 2<br />
1 0 3<br />
1 1 4<br />
<br />
Chip select pins on the ZX Breakout will be 67, 68, 71 and 74 for chip select 1 to 4 in that order.<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is 1, then it's still busy sending. Once bit 7 goes back low you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
Reads happen simultaneously to writes. SPI devices don't have an explicit RD or WR signal to specify which one is being done. When you write to an SPI device you get a read for free. If you need to read from a device, but it's not expecting to be written to, then write whatever the device's idle state (for example, 0xFF) is when you write to port 0x043B which will initiate the operation. The data sheet for the SPI device should specify what this is. Once the SPI operation is complete, and the 'busy' bit (bit 7 of the control register) has returned to zero, then reading port 0x043B will return whatever the SPI device deposited on the MISO line.<br />
<br />
The same comments about multiple writes in the above section (checking the control register's bit 7) applies to reading too, since they are effectively the same operation.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins and the adjacent pins on the top row.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select 1 (active low)<br />
68 Chip select 2 (active low)<br />
71 Chip select 3 (active low)<br />
74 Chip select 4 (active low)<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=398ZX SPI2013-06-19T21:15:24Z<p>Winston: </p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 1.75MHz to some absurdly low frequency (up to 16 stages of division, that would make 26 hertz!)<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Full duplex<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 70 macrocells (fits an XC9572)<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6-5 - SPI chip select to use<br />
bit 4-1 - set clock speed<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 1.5MHz, CPOL 0.<br />
<br />
If bit 5 is set to 1 when writing to the register, all other bits are ignored. This is to save the trouble of having to read the port back, merge in bit 5 and send it again (or storing the settings in memory).<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Busy, 0 = Ready for a new read/write operation<br />
bit 6-5 - SPI chip select in use<br />
bit 4-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI clock speed. The clock speed is determined by a simple 16 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. So to determine the amount that the 1.75MHz clock is divided by, take the value (0 to 15) and raise to the power of two. Here is a table of the most useful clock speeds:<br />
<br />
Bits 4-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
8 7kHz<br />
9 3.5kHz<br />
<br />
The ludicrously low speeds when the divider is set from 10 to 15 may be helpful while debugging, but probably not for actually running an SPI device!<br />
<br />
=== Chip selects ===<br />
<br />
There are four chip selects, so you can have up to 4 SPI devices. The active chip select is specified by bits 6 and 5 of the control register. The mapping looks like this:<br />
<br />
Bit 6 Bit 5 Chip select<br />
0 0 1<br />
0 1 2<br />
1 0 3<br />
1 1 4<br />
<br />
Chip select pins on the ZX Breakout will be 67, 68, 71 and 74 for chip select 1 to 4 in that order.<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is 1, then it's still busy sending. Once bit 7 goes back low you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
Reads happen simultaneously to writes. SPI devices don't have an explicit RD or WR signal to specify which one is being done. When you write to an SPI device you get a read for free. If you need to read from a device, but it's not expecting to be written to, then write whatever the device's idle state (for example, 0xFF) is when you write to port 0x043B which will initiate the operation. The data sheet for the SPI device should specify what this is. Once the SPI operation is complete, and the 'busy' bit (bit 7 of the control register) has returned to zero, then reading port 0x043B will return whatever the SPI device deposited on the MISO line.<br />
<br />
The same comments about multiple writes in the above section (checking the control register's bit 7) applies to reading too, since they are effectively the same operation.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins and the adjacent pins on the top row.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select 1 (active low)<br />
68 Chip select 2 (active low)<br />
71 Chip select 3 (active low)<br />
74 Chip select 4 (active low)<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=397ZX SPI2013-06-18T21:40:27Z<p>Winston: </p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 1.75MHz to some absurdly low frequency (up to 16 stages of division, that would make 26 hertz!)<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 81 macrocells.<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The Verilog code and Xilinx ISE project file can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6 - not used<br />
bit 5 - set to 1 to initiate an SPI read.<br />
bit 4-1 - set clock speed<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 1.5MHz, CPOL 0.<br />
<br />
If bit 5 is set to 1 when writing to the register, all other bits are ignored. This is to save the trouble of having to read the port back, merge in bit 5 and send it again (or storing the settings in memory).<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Ready to read or write (0 = currently reading or writing)<br />
bit 6 - 1 = SPI read has completed and there is data available<br />
bit 5 - Always zero<br />
bit 4-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI clock speed. The clock speed is determined by a simple 16 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. So to determine the amount that the 1.75MHz clock is divided by, take the value (0 to 15) and raise to the power of two. Here is a table of the most useful clock speeds:<br />
<br />
Bits 4-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
8 7kHz<br />
9 3.5kHz<br />
<br />
The ludicrously low speeds when the divider is set from 10 to 15 may be helpful while debugging, but probably not for actually running an SPI device!<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is zero, then it's still busy sending. Once bit 7 goes back high you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
This is a little more complex, since the SPI master (the Spectrum) must initiate the read. It's not like RS232 where the remote end can start sending at any moment and completely independently, an SPI master must generate the clock signal to read the byte and assert the chip select line. <br />
<br />
To start the SPI read, write out a value to the control register (port 0x053B) with bit 5 set to 1. When this bit is set to 1, all the other bits are ignored so you won't overwrite the clock speed or polarity settings. Then read back the control register. If bit 6 is set to 1, the read has completed. You can then read port 0x043B to get the byte. Just like for writes, if you're confident that the SPI read will be complete by the time you need to read port 0x043B, you can skip the check of the control register.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins. These are pins 61, 64, 66 and 67 on the CPLD and are labeled as such on the ZX Breakout.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select (active low)<br />
<br />
More chip selects can be easily added with a small modification to the Verilog. It's suggested that writing to bits 7 and 6 of the control register select which chip select pin is active if this is done.<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=396Main Page2013-06-18T21:33:34Z<p>Winston: </p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! They are sold via [http://www.sellmyretro.com/offer/details/*BRAND_NEW*_Sinclair_ZX_Spectrum_Spectranet_%28Ethernet_add-on%29-2511 RWAP Software] (who also sells other useful items like replacement keyboard membranes). The Spectranet is also available from the RWAP Software stand at retro events.<br />
<br />
WebSVN has been set up so that the Spectranet repository can be browsed and downloaded easily: see http://spectrum.alioth.net/svn .<br />
<br />
'''Latest Spectranet firmware''': R555 (released 5th March 2013)<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX SPI]] - an SPI interface written in Verilog for the [[ZX Breakout]].<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Spectramin]] - Spectrum 128K AY theremin<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[SpectraDVI]] - A digital video ULA+ add-on for the Spectrum?<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [http://spectrum.alioth.net/svn WebSVN] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_Breakout&diff=395ZX Breakout2013-06-18T21:32:05Z<p>Winston: </p>
<hr />
<div>[[Image:Zxbreakout1.jpg|thumb|right|500px|ZX Breakout with XC95144XL]]<br />
<br />
This is a CPLD (complex programmable logic device) breakout board for the Spectrum (including 128K and Amstrad models). The original idea behind this board was to provide a breakout board for the ZX Spectrum bus signals, and also level shifting of all the signals to 3.3v with a second set of breakout pins. This was to provide an interface to chips that are not 5v tolerant, such as all current in-production FPGAs.<br />
<br />
Using a CPLD instead of simple level shifters does two things: it provides the original functionality of a breakout board with a level shifter since a 3.3v CPLD with 5v tolerant IO can be used for this purpose, and for prototyping or making the logic for other things too - in other words, make a versatile breakout board for both the ZX bus and a CPLD.<br />
<br />
Either the Xilinx XC9572XL or the XC95144XL CPLD can be used on this board. To give a rough idea of the logic resources these CPLDs provide, Chris Smith's timing accurate ULA replacement fills an XC95144XL, that's to say this CPLD has a similiar amount of resource to the Spectrum ULA.<br />
<br />
=== Errata ===<br />
Due to a dumb mistake, the ROMCS circuit is incorrect for the black +2 and +3 machines. If you intend to use the ZX Breakout with one of these, a simple workaround is to just not connect pin 4 of the edge connector (top side, 4th pin from the left) or desolder it if you've already connected it. The board will not work at all with a black +2 or +3 unless you do this, even if you're not planning to use ROMCS. It works fine with all other models as-is.<br />
<br />
== The board ==<br />
<br />
[[Image:Zxbreakout.png|thumb|right|500px|ZX Breakout PCB]]<br />
<br />
The PCB features the following:<br />
<br />
* All major ZX bus digital signals routed to the CPLD.<br />
* Header for ZX signals, nearest the Spectrum edge connector.<br />
* 3.3v linear power supply for the CPLD.<br />
* JTAG header for programming the CPLD.<br />
* Ability to control the ROMCS line.<br />
* Clock is inverted (to be in phase with the CPU clock) by a Schmitt-trigger buffer giving sharper rising and falling edges.<br />
* Two headers for CPLD signals - a 40 pin header with 32 CPLD general purpose IOs, and a 10 pin header with 7 general purpose IOs.<br />
* 40 pin header laid out with ground and power pins in the same location as an IDE connector.<br />
* 4 layer PCB with solid ground and power planes for ideal CPLD performance.<br />
<br />
Additionally, the ZX signals and CPLD pin locations are shown in the silk screen, so you know what you're connecting to without having to reach for a datasheet.<br />
<br />
== Pin locations ==<br />
<br />
=== ZX bus to CPLD ===<br />
<br />
ZX bus function to CPLD function block mapping is optimized for the XC9572, being the smallest device with fewest resources. For the '72, the data bus and upper half of the address bus is grouped into function block 1, and the lower half of the address bus and control signals in function block 3. The remaining pins go to the GPIO headers.<br />
<br />
The ZX clock is mapped to a global clock signal, and the reset signal is inverted and buffered and routed to the global system reset pin. A global clock signal is available on the GPIO header.<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"| ZX signal<br />
! CPLD pin<br />
! XC9572 FB<br />
! XC95144 FB<br />
! Comments<br />
|- <br />
|D0||18||1||1||<br />
|- <br />
|D1||20||1||1||<br />
|-<br />
|D2||22||1||1||<br />
|- <br />
|D3||29||1||3||<br />
|-<br />
|D4||30||1||3||<br />
|- <br />
|D5||28||1||3||<br />
|-<br />
|D6||25||1||3||<br />
|- <br />
|D7||17||1||1||<br />
|-<br />
|A0||32||3||3||<br />
|- <br />
|A1||35||3||5||<br />
|-<br />
|A2||37||3||5||<br />
|- <br />
|A3||41||3||5||<br />
|-<br />
|A4||59||3||7||<br />
|- <br />
|A5||58||3||7||<br />
|-<br />
|A6||56||3||7||<br />
|- <br />
|A7||55||3||7||<br />
|-<br />
|A8||40||1||5||<br />
|- <br />
|A9||39||1||5||<br />
|-<br />
|A10||36||1||5||<br />
|- <br />
|A11||33||1||3||<br />
|-<br />
|A12||15||1||1||<br />
|- <br />
|A13||16||1||1||<br />
|-<br />
|A14||13||1||1||<br />
|- <br />
|A15||14||1||1||<br />
|-<br />
|/MREQ||50||3||7||<br />
|- <br />
|/IORQ||52||3||7||<br />
|-<br />
|/RD||53||3||7||<br />
|- <br />
|/WR||54||3||7||<br />
|-<br />
|/M1||60||3||7||<br />
|- <br />
|/INT||42||3||5||<br />
|-<br />
|/NMI||49||3||5||<br />
|-<br />
|CLK||23||1||5||Buffered; CPLD GCK2<br />
|-<br />
|RESET||99||2||3||Buffered; CPLD GSR (active high)<br />
|-<br />
|ROMCS||61||3||7||Only when "Use ROMCS" is jumpered<br />
|-<br />
|}<br />
<br />
=== 40 pin header ===<br />
<br />
The 40 pin header is numbered using the ribbon cable style of numbering. Pin 1 is at the top right hand side of the connector, when looking down at the component side of the PCB, with the ZX edge connector at the bottom (in other words, as shown in the image on this page).<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"| Header pin<br />
! CPLD pin<br />
! XC9572 FB<br />
! XC95144 FB<br />
! Comments<br />
|- <br />
|1||68||4||8||<br />
|- <br />
|2||GND||||||<br />
|-<br />
|3||71||4||8||<br />
|-<br />
|4||70||4||8||<br />
|-<br />
|5||74||4||6||<br />
|-<br />
|6||72||4||8||<br />
|-<br />
|7||77||4||6||<br />
|-<br />
|8||76||4||6||<br />
|-<br />
|9||79||4||6||<br />
|-<br />
|10||78||4||6||<br />
|-<br />
|11||82||4||6||<br />
|-<br />
|12||81||4||6||<br />
|-<br />
|13||86||4||6||<br />
|-<br />
|14||85||4||6||<br />
|-<br />
|15||89||4||4||<br />
|-<br />
|16||87||2||4||<br />
|-<br />
|17||91||2||4||<br />
|-<br />
|18||90||4||4||<br />
|-<br />
|19||GND||||||<br />
|-<br />
|20||3.3v||||||<br />
|-<br />
|21||92||2||4||<br />
|-<br />
|22||GND||||||<br />
|-<br />
|23||93||2||4||<br />
|-<br />
|24||GND||||||<br />
|-<br />
|25||94||2||4||<br />
|-<br />
|26||GND||||||<br />
|-<br />
|27||95||2||4||<br />
|-<br />
|28||96||2||4||<br />
|-<br />
|29||97||2||4||<br />
|-<br />
|30||GND||||||<br />
|-<br />
|31||1||2||2||<br />
|-<br />
|32||3||2||2||GTS1<br />
|-<br />
|33||4||2||2||GTS2<br />
|-<br />
|34||6||2||2||<br />
|-<br />
|35||8||2||2||<br />
|-<br />
|36||9||2||2||<br />
|-<br />
|37||10||2||2||<br />
|-<br />
|38||11||2||1||<br />
|-<br />
|39||12||2||1||<br />
|-<br />
|40||GND||||||<br />
|-<br />
|}<br />
<br />
=== 10 pin header ===<br />
<br />
This header uses ribbon cable numbering, with pin 1 being the top left pin looking down on the PCB, as in the image above.<br />
<br />
Pin 4 is the same as the ROMCS pin on the header next to the edge connector - it's just a straight connection. It is provided as an alternative site to connect a wire to ROMCS. Pin 9 is not connected to the CPLD if the "Use ROMCS" jumper is closed. When this jumper is closed, CPLD pin 61 will go to the transistor controlling the ROMCS line allowing the CPLD to page out the ZX ROM. Pin 10 routes to a global clock pin, it may also be used as general purpose IO.<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"| Header pin<br />
! CPLD pin<br />
! XC9572 FB<br />
! XC95144 FB<br />
! Comments<br />
|- <br />
|1||3.3v||||||<br />
|-<br />
|2||GND||||||<br />
|-<br />
|3||67||4||8||<br />
|-<br />
|4||ROMCS||||<br />
|-<br />
|5||66||4||8||<br />
|-<br />
|6||65||4||8||<br />
|-<br />
|7||64||3||8||<br />
|-<br />
|8||63||3||8||<br />
|-<br />
|9||61||3||7||May be routed to ROMCS<br />
|-<br />
|10||27||1||3||GCK3<br />
|-<br />
|}<br />
<br />
== Xilinx UCF file for pins ==<br />
<br />
Copy and paste this into your UCF text constraints file for the list of pins. Comment out the signals you aren't using with a # in front of that line (ISE will fail at the fitter stage if you have nets defined in your UCF file which don't exist in your design). Signals with "_L" at the end are active low. Note that RESET is active high (it's been inverted). This is generally what you want; the Xilinx library components all have active high reset. The clock is also in phase with the Z80 clock.<br />
<br />
Also note that the pin used to control ROMCS can also be used as a GPIO, depending on the position of the jumper. ROMCS is active low from the point of view of the CPLD.<br />
<br />
This file will also appear in Subversion.<br />
<br />
GPIO pins are not listed in this file since you'll be defining them according to whatever function they may have.<br />
<br />
net A(0) loc=p32;<br />
net A(1) loc=p35;<br />
net A(2) loc=p37;<br />
net A(3) loc=p41;<br />
net A(4) loc=p59;<br />
net A(5) loc=p58;<br />
net A(6) loc=p56;<br />
net A(7) loc=p55;<br />
<br />
net A(8) loc=p40;<br />
net A(9) loc=p39;<br />
net A(10) loc=p36;<br />
net A(11) loc=p33;<br />
net A(12) loc=p15;<br />
net A(13) loc=p16;<br />
net A(14) loc=p13;<br />
net A(15) loc=p14;<br />
<br />
net D(0) loc=p18;<br />
net D(1) loc=p20;<br />
net D(2) loc=p22;<br />
net D(3) loc=p29;<br />
net D(4) loc=p30;<br />
net D(5) loc=p28;<br />
net D(6) loc=p25;<br />
net D(7) loc=p17; <br />
<br />
net MREQ_L loc=p50;<br />
net IORQ_L loc=p52;<br />
net RD_L loc=p53;<br />
net WR_L loc=p54;<br />
net M1_L loc=p60;<br />
net INT_L loc=p42;<br />
net NMI_L loc=p49; <br />
<br />
net CLK loc=p23;<br />
net RESET loc=p99;<br />
<br />
net ROMCS_L loc=p61;<br />
<br />
== Components used ==<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"|Refdes<br />
! Component<br />
! Package<br />
! Mfr.<br />
! Description<br />
! Notes<br />
|- <br />
|U1||P565D2T33||D2PAK3||ON Semi||3.3v LDO regulator||<br />
|-<br />
|U2||74HCT14||SOIC 14||Any||Schmitt trigger inverter, TTL compatible||<br />
|-<br />
|U3||XC9572XL||TQFP 100||Xilinx||CPLD||Use XC95144XL for more logic resources<br />
|-<br />
|C1, C2||150uF||Tant B||Any||Capacitor||<br />
|-<br />
|C3||1uF||1206||Any||Capacitor||<br />
|-<br />
|C4 to C10||0.1uF||0603||Any||Capacitor||<br />
|-<br />
|R1||300R||0603||Any||Resistor||<br />
|-<br />
|Q1||BSS84P||SOT23||Infineon||P channel MOSFET||<br />
|-<br />
|}<br />
<br />
ZX bus edge connector is an open ended 28 position 0.1 inch pitch connector, with position 5 contacts removed and replaced with a plastic key. This connector usually needs to be hand made by cutting down a larger connector (such as an old ISA bus connector).<br />
<br />
40 pin, 10 pin and 60 pin headers are up to the board's user. It's suggested that SIL sockets are used for the headers since this allows wires to be plugged in and connected to a breadboard etc. However, if a ribbon cable is to be used, a PCB to ribbon connector is recommended.<br />
<br />
It is suggested that normal jumper pin headers are used for the jumpers.<br />
<br />
== Projects for the ZX Breakout ==<br />
<br />
* [[ZX SPI]] - An SPI interface for the Spectrum.<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_SPI&diff=394ZX SPI2013-06-18T21:30:17Z<p>Winston: Created page with "ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code. ''F..."</p>
<hr />
<div>ZXSPI is a Verilog project to allow the Spectrum with the ZX Breakout (or any other FPGA/CPLD board) to work as an SPI master without all that inelegant bit banging in code.<br />
<br />
''Features:''<br />
* SPI clock from 1.75MHz to some absurdly low frequency (up to 16 stages of division, that would make 26 hertz!)<br />
* Supports CPOL 0 (normal clock polarity) and CPOL 1 (inverted clock polarity)<br />
* Synchronous design that should work fine with an FPGA<br />
* Requires 81 macrocells.<br />
<br />
''Caveats:''<br />
I've not done a great deal of Verilog, so it's likely the implementation can be made a bit more efficient. In particular, the parallel to serial and serial to parallel shift registers are double buffered, it's the easiest way of separating the two clock domains (Z80 clock and SPI clock domains), but it's probably possible to do something more convoluted that uses fewer flip flops. I've also not had the opportunity to test SPI reads on real hardware, only on the ISE simulator. It *should* work, but I need to get an SPI device that can be read from to test it.<br />
<br />
The code can be obtained [http://spectrum.alioth.net/svn/listing.php?repname=ZXSPI&path=%2Ftrunk%2Fise%2F#path_trunk_ise_ here, from WebSVN]<br />
<br />
== Using ZXSPI ==<br />
<br />
The project uses two IO ports, performing full 16 bit port decoding:<br />
<br />
* Port 0x043B: SPI read/write<br />
* Port 0x053B: Control and status register.<br />
<br />
=== The control and status register ===<br />
<br />
When writing to the register, the following bits are defined:<br />
<br />
bit 7 - not used<br />
bit 6 - not used<br />
bit 5 - set to 1 to initiate an SPI read.<br />
bit 4-1 - set clock speed<br />
bit 0 - select clock polarity (0 = CPOL 0, 1 = CPOL 1)<br />
<br />
After the Spectrum is powered up or reset, the defaults are: Clock speed 1.5MHz, CPOL 0.<br />
<br />
If bit 5 is set to 1 when writing to the register, all other bits are ignored. This is to save the trouble of having to read the port back, merge in bit 5 and send it again (or storing the settings in memory).<br />
<br />
When reading from the register, the following bits are defined:<br />
<br />
bit 7 - 1 = Ready to read or write (0 = currently reading or writing)<br />
bit 6 - 1 = SPI read has completed and there is data available<br />
bit 5 - Always zero<br />
bit 4-1 - Current clock speed<br />
bit 0 - Current clock polarity<br />
<br />
=== Setting SPI clock speed ===<br />
<br />
Bits 4-1 of the control register (0x053B) set the SPI clock speed. The clock speed is determined by a simple 16 stage clock divider. The fastest speed (1.75MHz) is basically the Z80 clock divided by two. So to determine the amount that the 1.75MHz clock is divided by, take the value (0 to 15) and raise to the power of two. Here is a table of the most useful clock speeds:<br />
<br />
Bits 4-1 Speed<br />
0 1.75MHz<br />
1 875kHz<br />
2 438kHz<br />
3 219kHz<br />
4 109kHz<br />
5 55kHz<br />
6 27kHz<br />
7 14kHz<br />
8 7kHz<br />
9 3.5kHz<br />
<br />
The ludicrously low speeds when the divider is set from 10 to 15 may be helpful while debugging, but probably not for actually running an SPI device!<br />
<br />
=== Writing to an SPI device ===<br />
<br />
After setting the SPI clock to the desired speed, writing is simply a matter of sending the byte you want to send to port 0x043B. If you need to send several bytes, and you know that the 8 bits will be written out on the SPI bus before you send the next byte, you can just write again to port 0x043B. However, if your code is in a tight machine code loop and the SPI clock is a low enough speed, it's likely the SPI write won't have finished. (A future update may be to not transfer the byte into the shift register until the previous byte has been sent so that two may be sent at once, but this is currently not the case). To check whether you can send another byte, read the control and status register and check the state of bit 7. If bit 7 is zero, then it's still busy sending. Once bit 7 goes back high you can send a new byte.<br />
<br />
=== Reading from an SPI device ===<br />
<br />
This is a little more complex, since the SPI master (the Spectrum) must initiate the read. It's not like RS232 where the remote end can start sending at any moment and completely independently, an SPI master must generate the clock signal to read the byte and assert the chip select line. <br />
<br />
To start the SPI read, write out a value to the control register (port 0x053B) with bit 5 set to 1. When this bit is set to 1, all the other bits are ignored so you won't overwrite the clock speed or polarity settings. Then read back the control register. If bit 6 is set to 1, the read has completed. You can then read port 0x043B to get the byte. Just like for writes, if you're confident that the SPI read will be complete by the time you need to read port 0x043B, you can skip the check of the control register.<br />
<br />
== Default pins ==<br />
<br />
If you don't modify the UCF file in the project, the SPI pins appear on the connector on the right hand side of the board, on the innermost column of pins. These are pins 61, 64, 66 and 67 on the CPLD and are labeled as such on the ZX Breakout.<br />
<br />
The pin assignments by default are:<br />
<br />
61 SPI clock (often known as SCL)<br />
64 MOSI (master out slave in)<br />
66 MISO (master in slave out)<br />
67 Chip select (active low)<br />
<br />
More chip selects can be easily added with a small modification to the Verilog. It's suggested that writing to bits 7 and 6 of the control register select which chip select pin is active if this is done.<br />
<br />
[[Category:ZX Breakout]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=393Main Page2013-06-18T20:50:02Z<p>Winston: /* Project Info */</p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! They are sold via [http://www.sellmyretro.com/offer/details/*BRAND_NEW*_Sinclair_ZX_Spectrum_Spectranet_%28Ethernet_add-on%29-2511 RWAP Software] (who also sells other useful items like replacement keyboard membranes). The Spectranet is also available from the RWAP Software stand at retro events.<br />
<br />
WebSVN has been set up so that the Spectranet repository can be browsed and downloaded easily: see http://spectrum.alioth.net/svn .<br />
<br />
'''Latest Spectranet firmware''': R554 (released 19th Jan 2013)<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX Breakout]] allows CPLD development and easy access to ZX bus signals on a pin header.<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Spectramin]] - Spectrum 128K AY theremin<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
** [[ZX SPI]] - An SPI interface for the ZX Breakout allowing the Spectrum to become an SPI master.<br />
* [[SpectraDVI]] - A digital video ULA+ add-on for the Spectrum?<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [http://spectrum.alioth.net/svn WebSVN] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=392Main Page2013-05-28T21:30:37Z<p>Winston: </p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! They are sold via [http://www.sellmyretro.com/offer/details/*BRAND_NEW*_Sinclair_ZX_Spectrum_Spectranet_%28Ethernet_add-on%29-2511 RWAP Software] (who also sells other useful items like replacement keyboard membranes). The Spectranet is also available from the RWAP Software stand at retro events.<br />
<br />
WebSVN has been set up so that the Spectranet repository can be browsed and downloaded easily: see http://spectrum.alioth.net/svn .<br />
<br />
'''Latest Spectranet firmware''': R554 (released 19th Jan 2013)<br />
<br />
'''TNFS server updated''': Get it from the [[Downloads]] section (released 28th May 2013)<br />
<br />
'''New!''' [[ZX Breakout]] allows CPLD development and easy access to ZX bus signals on a pin header.<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Spectramin]] - Spectrum 128K AY theremin<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
* [[SpectraDVI]] - A digital video ULA+ add-on for the Spectrum?<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [http://spectrum.alioth.net/svn WebSVN] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Spectranet:_Tutorial_2&diff=391Spectranet: Tutorial 22013-02-03T09:52:35Z<p>Winston: /* Using telnet to test the code */</p>
<hr />
<div>For the first practical session, we'll start with a TCP server. We'll start with this because it's easy to play with: all you need for the other end of the connection (on, for example, a PC) to play with it is the '''telnet''' command. Even better than telnet is '''netcat''' (the 'nc' command) which comes by default with most Unixy type operating systems (Linux, BSD etc.), but if you don't have netcat, telnet suffices. Whether you run Windows, Mac OS X or something else, you'll have a telnet client. Telnet is also tremendously useful for simple debugging of various networked services, so it's as well to introduce it at this point.<br />
<br />
This tutorial will be concerned with writing a simple TCP server which can handle one connection; the 'hello world' of network server programs.<br />
<br />
== What does a server program need to do? ==<br />
<br />
All server programs on a TCP socket will do the following:<br />
<br />
* Open a socket.<br />
* Bind it to a port.<br />
* Tell the socket to start listening.<br />
* Accept any incoming connections.<br />
* Transfer some data.<br />
* Close the connection when done.<br />
<br />
Opening a socket is pretty self explanatory - it allocates the resources associated with what you eventually want to be a connection to a remote machine. It's the first step of any networked program, whether it's for TCP, UDP, a server or a client. When you successfully open a socket, you get something back called a '''file descriptor''' or '''socket handle'''. If you're a Unix programmer, you'll know them as file descriptors. Windows programmers will know them as socket handles. It doesn't matter - they are the same thing - it's basically an identifier for the system to the socket you've just opened. However, an open socket on its own isn't a lot of use - you have to tell the system what you want to do with it. The bind operation associates a socket with a local port, for example, port 80 if it was a web server. But even then, the socket doesn't do much - because it doesn't yet know whether you want to connect to a remote host with it, or listen with it. In the case of a server the next step is to tell it to listen.<br />
<br />
Once you've done open, bind, and listen, the socket is finally in a state where it will do something! A remote machine can now try to connect. There's still one more step though - when a machine connects, the server needs to accept the connection.<br />
<br />
Accept does something very interesting. It doesn't merely tell the TCP stack to do all the necessary stuff to get the socket into the established state - it actually creates a completely new socket which is a clone of the one you opened, with a brand new file descriptor. This new socket is actually the one you'll send and receive data on. The original socket continues to listen for further connections. So when you come to sending data you won't be using the original file descriptor. When you close the connection that you accepted, it doesn't affect the state of the original listening socket.<br />
<br />
== The code ==<br />
<br />
The following code snippets show how all the above is done, in both assembly language and C. To see the code in context, you should open the following link in a new tab or browser window - the example assembly code for this tutorial is here: [http://spectrum.alioth.net/svn/filedetails.php?repname=Spectranet&path=%2Ftrunk%2Fexamples%2Ftutorial2%2Fsimpleserv.asm]. The example C code is here: [http://spectrum.alioth.net/svn/filedetails.php?repname=Spectranet&path=%2Ftrunk%2Fexamples%2Ftutorial2%2Fsimpleserv.c]<br />
<br />
If you're using assembly language, your code should include the file spectranet.asm, available here: [http://spectrum.alioth.net/svn/filedetails.php?repname=Spectranet&path=%2Ftrunk%2From%2Fspectranet.asm] . This file has all the symbols you need to call the ROM code. C users, using the Z88DK should include the relevant includes - normally at least <sys/socket.h> and <sys/types.h>, and link with the library libsocket.<br />
<br />
=== Using telnet to test the code ===<br />
<br />
'''Note''': Microsoft has removed the 'telnet' command in Windows 7 and newer. Download PuTTY and use this instead. If you're using Linux, sometimes telnet is not installed by default, however netcat (nc) is often installed. Usually installing either telnet or netcat on Linux is very straight forward (apt-get install telnet or yum install telnet, depending on distro).<br />
<br />
If you assemble or compile the example code, and load it onto a Spectrum, you can try it out by typing RANDOMIZE USR 32768 on the Spectrum. Then on another machine, such as a PC or Mac, you can try connecting to it as follows. Open a command prompt or shell (in Windows, Start -> Run program, and type 'cmd', in Mac OS X, Linux or BSD, open a terminal window), and then type:<br />
<br />
telnet <ip-address-of-your-spectrum> 2000<br />
<br />
for example, if your Spectrum is at 172.16.0.38:<br />
<br />
telnet 172.16.0.38 2000<br />
<br />
...and you should immediately get the message 'Hello world', and the Spectrum will display 'Connection established.' You can then type a string into telnet, which the Spectrum will display. If you start the string with the letter 'x', the example program on the Spectrum will exit.<br />
<br />
=== Opening the socket ===<br />
<br />
This is a very simple operation. In assembly language, there is only one parameter - the socket type you want to open, which may be SOCK_STREAM or SOCK_DGRAM. The TCP socket is of type SOCK_STREAM. It's passed in the C register:<br />
<br />
ld c, SOCK_STREAM ; The kind of socket we want - a stream - i.e. TCP<br />
ld hl, SOCKET ; The address of the socket() routine<br />
call HLCALL ; Call it<br />
jr c, .error ; Handle any errors<br />
ld (v_sockfd), a ; Save the socket handle somewhere in memory<br />
<br />
You'll note a couple of things about this code. Firstly, we don't just 'call SOCKET'. This is because under normal circumstances, the Spectrum ROM will be paged in, and the Spectranet won't be. There are three entry points that cause a page-in. HLCALL and IXCALL cause the Spectranet to page its ROM in, call the address in HL (or IX in the case of IXCALL), and when the call is finished, page out again (so the normal Spectrum ROM is available). The second thing you'll note is that the carry flag is used to indicate whether the call succeeded or not. For all the Spectranet ROM calls that can report an error, the carry flag is set on error, and the A register contains the error code.<br />
<br />
For C users, opening the socket is done like this:<br />
<br />
int sockfd;<br />
sockfd=socket(AF_INET, SOCK_STREAM, 0);<br />
<br />
If an error occurs, sockfd is set to a negative value. Nearly all the socket library functions return a negative value on error, and 0 or a positive value on success. The current Spectranet hardware doesn't support anything other than AF_INET sockets - but be sure to set the first parameter, because one day at least AF_INET6 may be supported too. The last parameter should be set to 0 (the default protocol; the Spectranet doesn't yet support anything else).<br />
<br />
So now we have a valid socket file descriptor (or socket handle), which we can now do operations on. The ROM code has allocated resources for the socket - poked the various hardware registers to allocate hardware resources, and set a couple of system variables to associate the hardware register set with the socket file descriptor.<br />
<br />
Another thing to note at this stage is that since you've allocated these resources, you need to be careful to de-allocate them and not leak socket handles, or you'll run out of hardware resources! Note that sockets don't get automatically closed if your program exits...so be sure to close them in your exit routines. (Pressing the reset button will, however, clear everything out).<br />
<br />
=== Associating the socket with a port ===<br />
<br />
You've probably noticed that programs on the internet don't just have a server address, but a port, too. Ones you may know already are HTTP for the world wide web, on port 80, the secure shell on port 22, or FTP which uses both port 21 and a randomly assigned port. The next step in a server program is to associate the socket with the port it'll listen on with the '''bind''' function.<br />
<br />
In assembler, the operation is very simple. We'll assume that the A register still contains the socket file descriptor - if not, just retrieve it from memory. There's no return code unless an error occurs, and the port to bind to is passed in the DE register pair, in machine byte order (the BIND function takes care of converting it to network byte order).<br />
<br />
ld de, 2000 ; The port we want to listen on.<br />
ld hl, BIND ; Call the BIND function<br />
call HLCALL <br />
jr c, .error ; Carry flag = error<br />
<br />
The C interface is a bit more formal about things. Firstly, there's a structure, '''struct sockaddr_in''', which is a general purpose internet address structure (hence the name sockaddr_in - socket address, internet). This must be set up with the port.<br />
<br />
struct sockaddr_in my_addr;<br />
....<br />
my_addr.sin_family=AF_INET;<br />
my_addr.sin_port=htons(2000);<br />
<br />
You'll note the macro htons here. This converts a machine order (little endian) integer into a network order (big endian) value. Except here, it's actually a no-op - because the underlying BIND function in ROM does this for us. You should still use htons - it won't bloat your code (since it's a macro that doesn't do anything) but it's a good habit in case you do network code on other machines where it is '''not''' a no-op!<br />
<br />
Now call bind:<br />
<br />
if(bind(sockfd, &my_addr, sizeof(my_addr)) < 0)<br />
{<br />
handle_error();<br />
return;<br />
}<br />
<br />
The first argument to bind() is the file descriptor, the second is the address of the sockaddr_in structure you made earlier, and the last argument is the size of this structure.<br />
<br />
If all went well, the socket is now bound to a local address (in our case, that just means it's associated with a port).<br />
<br />
=== Tell the socket to listen ===<br />
<br />
This is a very simple operation. Just pass the file descriptor to the listen function. In assembler, you do it like this:<br />
<br />
ld a, (v_sockfd) ; get the socket file descriptor<br />
ld hl, LISTEN ; for the LISTEN function call<br />
call HLCALL<br />
jr c, .error<br />
<br />
It's also a very simple operation in C.<br />
<br />
if(listen(sockfd, 1) < 0)<br />
{<br />
handle_error();<br />
return;<br />
}<br />
<br />
Note the second parameter in the C library call. This is the allowed backlog. The hardware currently doesn't support changing the backlog, but set this to something sensible in case it eventually does.<br />
<br />
=== Wait for a connection, and accept it ===<br />
<br />
Things get a bit more interesting at this point, since there's more than one way of accomplishing this. However, for this tutorial, we'll concentrate on the simple case - just block until someone connects. The accept function will do just this if called before any remote host has tried to connect - it won't return until someone connects, and when it does, it'll return with the file descriptor of the accepted socket.<br />
<br />
That last sentence is very important: it's at this point we're actually going to get a new socket created. The accept call does all this for you - it will block until someone connects, and when they do, it'll clone the listening socket, and return a completely new socket file descriptor which you use for communicating with the remote host. The original socket you opened in the first three steps is still open, and the accept function can accept further connections from this socket. We won't worry about that in this tutorial though - this example will be written just to handle a single client.<br />
<br />
For the assembly version, we've got another byte in memory for storing this new file descriptor, called v_connfd. It's just another integer.<br />
<br />
ld a, (v_sockfd) ; The listening socket we did open, bind and listen on.<br />
ld hl, ACCEPT ; The accept call.<br />
call HLCALL ; Call accept, and block until someone connects to us.<br />
jr c, .error ; carry set = error occurred<br />
ld (v_connfd), a ; Save the new socket file descriptor<br />
<br />
In C, the same operation is done as follows:<br />
<br />
connfd=accept(sockfd, NULL, NULL);<br />
if(connfd > 0)<br />
{<br />
...<br />
}<br />
<br />
The two parameters set to NULL are for a struct sockaddr_in* pointer, and structure length. We won't worry too much about them now, but if they are filled in, accept will fill the structure with the address of the remote host that connected to this program.<br />
<br />
=== Send and receive data ===<br />
<br />
Data is sent and received with the send and recv functions, respectively. You can think of send and recv a bit like the BASIC keywords PRINT and INPUT - send will send the data and return immediately (unless the transmit buffer is full), and recv - like INPUT, will block until there's data ready to be returned to the program. There are some other details, too.<br />
<br />
For sending data, we'll assume we've got a buffer somewhere in memory containing the string 'Hello world\n' (i.e. 'Hello world' with a newline), and we want to send this 12-byte chunk of data. In assembler this is what you need to do:<br />
<br />
ld a, (v_connfd) ; file descriptor of the connection we accepted earlier<br />
ld de, BUF_hello ; memory address of the buffer containing 'Hello world\n'<br />
ld bc, 12 ; which is 12 bytes long<br />
ld hl, SEND ; call the SEND function<br />
call HLCALL<br />
jr c, .error ; did it work?<br />
<br />
The ROM call for SEND therefore takes three arguments. The socket file descriptor is passed in the A register. DE contains the address of the block of data to send. BC is set to the number of bytes to send. When SEND returns, if all is well, BC is set to the number of bytes actually sent.<br />
<br />
The C library call is essentially the same, with just one extra parameter, ''flags'' (which currently should be left set to 0).<br />
<br />
char *hstring="Hello world\n";<br />
...<br />
bytes=send(connfd, hstring, strlen(hstring), 0);<br />
<br />
A negative value is returned in case of an error, but otherwise, send returns the number of bytes sent.<br />
<br />
The recv call is very similar - again, it takes the socket on which to receive data, an address of a buffer (in this case, the address of a block of memory to fill), and the size of the buffer. It returns how many bytes were actually received. Note that recv doesn't attempt to fill the entire buffer you give it - the size of the buffer is just the maximum amount of data it will return. If some data that's less than the size of the buffer is received, recv returns this - so it's important to check the number of bytes returned in case you expect more than you actually got! The recv call will block until some data is received. (How to stop your program from stopping until someone sends some data will be covered in the multiplexing tutorial).<br />
<br />
In assembler, recv is used like this:<br />
<br />
ld a, (v_connfd) ; Get the connection file descriptor.<br />
ld de, BUF_receive ; Set DE to the address of a buffer to fill with data<br />
ld bc, 512 ; The buffer pointed to by DE is 512 bytes long.<br />
ld hl, RECV ; Call the RECV function.<br />
call HLCALL ; ...and BC will contain the number of bytes actually received<br />
jr c, .error<br />
<br />
As with send, the RECV function takes three arguments: A contains the socket file descriptor, the DE register pair contains the address off the start of a buffer in memory to fill, and BC contains the maximum amount of data that RECV should put in this buffer. On return, the BC register pair contains the number of bytes actually received, which in many cases will probably be less than the size of the buffer.<br />
<br />
The C call is similar, too:<br />
<br />
char buf[512]; /* allocate a 512 byte buffer */<br />
....<br />
bytes=recv(connfd, buf, sizeof(buf), 0);<br />
<br />
Again, the ''flags'' parameter should be set to zero. If an error occurs, recv returns a negative value.<br />
<br />
=== Closing the connection ===<br />
<br />
Once you're done with a socket, it should be closed. It's important to explicitly do this - while in Unix or Windows, all file descriptors and memory gets cleaned up when a program exits, the Spectrum doesn't really have this concept - so if your program is going to get invoked multiple times, it's important to make sure all sockets are closed when it exits. Many programs will need to service many connections that come and go, for example, a web server will have to open, service and close perhaps dozens of connections a second. Even on a big mainframe, if you didn't clean up the socket file descriptors you could end up running out.<br />
<br />
The close routine does this. If your server is going to be servicing more connections, the original socket should be left open, since this is the one you're listening on, and just the connection sockets should be closed when they are done with (except, of course, when your program exits, at which point you'll want to close your listening socket, too). The close routine is very simple:<br />
<br />
ld a, (v_connfd) ; get the connection's file descriptor<br />
ld hl, CLOSE<br />
call HLCALL<br />
jr c, .error<br />
<br />
So what errors can happen on close? If your program has a bug, you might end up trying to close a socket file descriptor that doesn't actually exist.<br />
<br />
The C close routine is called sockclose. This is because the Z88DK doesn't yet have a truly generalized fcntl, so the z88dk close() routine doesn't know how to close a socket. The sockclose routine, therefore, only works on socket file descriptors and not, say, a file descriptor for a file on disc. This may well change; the z88dk developers are working on a more generalized fcntl right now.<br />
<br />
In C, closing a socket is as simple as:<br />
<br />
if(sockclose(connfd) < 0)<br />
{<br />
handle_error();<br />
return;<br />
}<br />
<br />
== In summary ==<br />
<br />
As you've seen, a simple TCP server consists of creating the socket with the '''[[socket]]''' routine, binding it to a port with '''[[bind]]''', telling it to listen with '''[[listen]]''', accepting an incoming connection with '''[[accept]]''', then sending and receiving data with '''[[send]]''' and '''[[recv]]'''. Once the connection's done, it's closed with '''[[close]]''', or '''[[sockclose]]''' if you're using the z88dk. Both accept and recv block until they get a connection and data respectively, but there are ways to avoid blocking - which will be discussed in a later tutorial.<br />
<br />
In the next tutorial, we'll cover writing a TCP client.<br />
<br />
[[Spectranet: Tutorial 3]]<br />
<br />
== Further reading ==<br />
<br />
Practical code: The simple loader tool, from the utility ROM's NMI menu, which is a simple server that receives data on port 2000 and puts this data into the Spectrum's RAM: [http://spectrum.alioth.net/svn/filedetails.php?repname=Spectranet&path=%2Ftrunk%2From%2Futilnmi.asm] - see the F_loader routine.<br />
<br />
Reference manuals for the functions used:<br />
<br />
* [[socket]]<br />
* [[bind]]<br />
* [[listen]]<br />
* [[accept]]<br />
* [[send]]<br />
* [[recv]]<br />
* [[close]]<br />
<br />
[[Category:Spectranet]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Spectranet:_Tutorial_2&diff=390Spectranet: Tutorial 22013-02-03T09:52:05Z<p>Winston: /* Using telnet to test the code */</p>
<hr />
<div>For the first practical session, we'll start with a TCP server. We'll start with this because it's easy to play with: all you need for the other end of the connection (on, for example, a PC) to play with it is the '''telnet''' command. Even better than telnet is '''netcat''' (the 'nc' command) which comes by default with most Unixy type operating systems (Linux, BSD etc.), but if you don't have netcat, telnet suffices. Whether you run Windows, Mac OS X or something else, you'll have a telnet client. Telnet is also tremendously useful for simple debugging of various networked services, so it's as well to introduce it at this point.<br />
<br />
This tutorial will be concerned with writing a simple TCP server which can handle one connection; the 'hello world' of network server programs.<br />
<br />
== What does a server program need to do? ==<br />
<br />
All server programs on a TCP socket will do the following:<br />
<br />
* Open a socket.<br />
* Bind it to a port.<br />
* Tell the socket to start listening.<br />
* Accept any incoming connections.<br />
* Transfer some data.<br />
* Close the connection when done.<br />
<br />
Opening a socket is pretty self explanatory - it allocates the resources associated with what you eventually want to be a connection to a remote machine. It's the first step of any networked program, whether it's for TCP, UDP, a server or a client. When you successfully open a socket, you get something back called a '''file descriptor''' or '''socket handle'''. If you're a Unix programmer, you'll know them as file descriptors. Windows programmers will know them as socket handles. It doesn't matter - they are the same thing - it's basically an identifier for the system to the socket you've just opened. However, an open socket on its own isn't a lot of use - you have to tell the system what you want to do with it. The bind operation associates a socket with a local port, for example, port 80 if it was a web server. But even then, the socket doesn't do much - because it doesn't yet know whether you want to connect to a remote host with it, or listen with it. In the case of a server the next step is to tell it to listen.<br />
<br />
Once you've done open, bind, and listen, the socket is finally in a state where it will do something! A remote machine can now try to connect. There's still one more step though - when a machine connects, the server needs to accept the connection.<br />
<br />
Accept does something very interesting. It doesn't merely tell the TCP stack to do all the necessary stuff to get the socket into the established state - it actually creates a completely new socket which is a clone of the one you opened, with a brand new file descriptor. This new socket is actually the one you'll send and receive data on. The original socket continues to listen for further connections. So when you come to sending data you won't be using the original file descriptor. When you close the connection that you accepted, it doesn't affect the state of the original listening socket.<br />
<br />
== The code ==<br />
<br />
The following code snippets show how all the above is done, in both assembly language and C. To see the code in context, you should open the following link in a new tab or browser window - the example assembly code for this tutorial is here: [http://spectrum.alioth.net/svn/filedetails.php?repname=Spectranet&path=%2Ftrunk%2Fexamples%2Ftutorial2%2Fsimpleserv.asm]. The example C code is here: [http://spectrum.alioth.net/svn/filedetails.php?repname=Spectranet&path=%2Ftrunk%2Fexamples%2Ftutorial2%2Fsimpleserv.c]<br />
<br />
If you're using assembly language, your code should include the file spectranet.asm, available here: [http://spectrum.alioth.net/svn/filedetails.php?repname=Spectranet&path=%2Ftrunk%2From%2Fspectranet.asm] . This file has all the symbols you need to call the ROM code. C users, using the Z88DK should include the relevant includes - normally at least <sys/socket.h> and <sys/types.h>, and link with the library libsocket.<br />
<br />
=== Using telnet to test the code ===<br />
<br />
'''Note''': Microsoft has removed the 'telnet' command in Windows 7 and newer. Download PuTTY and use this instead. If you're using Linux, sometimes telnet is not installed by default, however netcat (nc) is often installed. Usually installint either telnet or netcat on Linux is very straight forward (apt-get install telnet or yum install telnet, depending on distro).<br />
<br />
If you assemble or compile the example code, and load it onto a Spectrum, you can try it out by typing RANDOMIZE USR 32768 on the Spectrum. Then on another machine, such as a PC or Mac, you can try connecting to it as follows. Open a command prompt or shell (in Windows, Start -> Run program, and type 'cmd', in Mac OS X, Linux or BSD, open a terminal window), and then type:<br />
<br />
telnet <ip-address-of-your-spectrum> 2000<br />
<br />
for example, if your Spectrum is at 172.16.0.38:<br />
<br />
telnet 172.16.0.38 2000<br />
<br />
...and you should immediately get the message 'Hello world', and the Spectrum will display 'Connection established.' You can then type a string into telnet, which the Spectrum will display. If you start the string with the letter 'x', the example program on the Spectrum will exit.<br />
<br />
=== Opening the socket ===<br />
<br />
This is a very simple operation. In assembly language, there is only one parameter - the socket type you want to open, which may be SOCK_STREAM or SOCK_DGRAM. The TCP socket is of type SOCK_STREAM. It's passed in the C register:<br />
<br />
ld c, SOCK_STREAM ; The kind of socket we want - a stream - i.e. TCP<br />
ld hl, SOCKET ; The address of the socket() routine<br />
call HLCALL ; Call it<br />
jr c, .error ; Handle any errors<br />
ld (v_sockfd), a ; Save the socket handle somewhere in memory<br />
<br />
You'll note a couple of things about this code. Firstly, we don't just 'call SOCKET'. This is because under normal circumstances, the Spectrum ROM will be paged in, and the Spectranet won't be. There are three entry points that cause a page-in. HLCALL and IXCALL cause the Spectranet to page its ROM in, call the address in HL (or IX in the case of IXCALL), and when the call is finished, page out again (so the normal Spectrum ROM is available). The second thing you'll note is that the carry flag is used to indicate whether the call succeeded or not. For all the Spectranet ROM calls that can report an error, the carry flag is set on error, and the A register contains the error code.<br />
<br />
For C users, opening the socket is done like this:<br />
<br />
int sockfd;<br />
sockfd=socket(AF_INET, SOCK_STREAM, 0);<br />
<br />
If an error occurs, sockfd is set to a negative value. Nearly all the socket library functions return a negative value on error, and 0 or a positive value on success. The current Spectranet hardware doesn't support anything other than AF_INET sockets - but be sure to set the first parameter, because one day at least AF_INET6 may be supported too. The last parameter should be set to 0 (the default protocol; the Spectranet doesn't yet support anything else).<br />
<br />
So now we have a valid socket file descriptor (or socket handle), which we can now do operations on. The ROM code has allocated resources for the socket - poked the various hardware registers to allocate hardware resources, and set a couple of system variables to associate the hardware register set with the socket file descriptor.<br />
<br />
Another thing to note at this stage is that since you've allocated these resources, you need to be careful to de-allocate them and not leak socket handles, or you'll run out of hardware resources! Note that sockets don't get automatically closed if your program exits...so be sure to close them in your exit routines. (Pressing the reset button will, however, clear everything out).<br />
<br />
=== Associating the socket with a port ===<br />
<br />
You've probably noticed that programs on the internet don't just have a server address, but a port, too. Ones you may know already are HTTP for the world wide web, on port 80, the secure shell on port 22, or FTP which uses both port 21 and a randomly assigned port. The next step in a server program is to associate the socket with the port it'll listen on with the '''bind''' function.<br />
<br />
In assembler, the operation is very simple. We'll assume that the A register still contains the socket file descriptor - if not, just retrieve it from memory. There's no return code unless an error occurs, and the port to bind to is passed in the DE register pair, in machine byte order (the BIND function takes care of converting it to network byte order).<br />
<br />
ld de, 2000 ; The port we want to listen on.<br />
ld hl, BIND ; Call the BIND function<br />
call HLCALL <br />
jr c, .error ; Carry flag = error<br />
<br />
The C interface is a bit more formal about things. Firstly, there's a structure, '''struct sockaddr_in''', which is a general purpose internet address structure (hence the name sockaddr_in - socket address, internet). This must be set up with the port.<br />
<br />
struct sockaddr_in my_addr;<br />
....<br />
my_addr.sin_family=AF_INET;<br />
my_addr.sin_port=htons(2000);<br />
<br />
You'll note the macro htons here. This converts a machine order (little endian) integer into a network order (big endian) value. Except here, it's actually a no-op - because the underlying BIND function in ROM does this for us. You should still use htons - it won't bloat your code (since it's a macro that doesn't do anything) but it's a good habit in case you do network code on other machines where it is '''not''' a no-op!<br />
<br />
Now call bind:<br />
<br />
if(bind(sockfd, &my_addr, sizeof(my_addr)) < 0)<br />
{<br />
handle_error();<br />
return;<br />
}<br />
<br />
The first argument to bind() is the file descriptor, the second is the address of the sockaddr_in structure you made earlier, and the last argument is the size of this structure.<br />
<br />
If all went well, the socket is now bound to a local address (in our case, that just means it's associated with a port).<br />
<br />
=== Tell the socket to listen ===<br />
<br />
This is a very simple operation. Just pass the file descriptor to the listen function. In assembler, you do it like this:<br />
<br />
ld a, (v_sockfd) ; get the socket file descriptor<br />
ld hl, LISTEN ; for the LISTEN function call<br />
call HLCALL<br />
jr c, .error<br />
<br />
It's also a very simple operation in C.<br />
<br />
if(listen(sockfd, 1) < 0)<br />
{<br />
handle_error();<br />
return;<br />
}<br />
<br />
Note the second parameter in the C library call. This is the allowed backlog. The hardware currently doesn't support changing the backlog, but set this to something sensible in case it eventually does.<br />
<br />
=== Wait for a connection, and accept it ===<br />
<br />
Things get a bit more interesting at this point, since there's more than one way of accomplishing this. However, for this tutorial, we'll concentrate on the simple case - just block until someone connects. The accept function will do just this if called before any remote host has tried to connect - it won't return until someone connects, and when it does, it'll return with the file descriptor of the accepted socket.<br />
<br />
That last sentence is very important: it's at this point we're actually going to get a new socket created. The accept call does all this for you - it will block until someone connects, and when they do, it'll clone the listening socket, and return a completely new socket file descriptor which you use for communicating with the remote host. The original socket you opened in the first three steps is still open, and the accept function can accept further connections from this socket. We won't worry about that in this tutorial though - this example will be written just to handle a single client.<br />
<br />
For the assembly version, we've got another byte in memory for storing this new file descriptor, called v_connfd. It's just another integer.<br />
<br />
ld a, (v_sockfd) ; The listening socket we did open, bind and listen on.<br />
ld hl, ACCEPT ; The accept call.<br />
call HLCALL ; Call accept, and block until someone connects to us.<br />
jr c, .error ; carry set = error occurred<br />
ld (v_connfd), a ; Save the new socket file descriptor<br />
<br />
In C, the same operation is done as follows:<br />
<br />
connfd=accept(sockfd, NULL, NULL);<br />
if(connfd > 0)<br />
{<br />
...<br />
}<br />
<br />
The two parameters set to NULL are for a struct sockaddr_in* pointer, and structure length. We won't worry too much about them now, but if they are filled in, accept will fill the structure with the address of the remote host that connected to this program.<br />
<br />
=== Send and receive data ===<br />
<br />
Data is sent and received with the send and recv functions, respectively. You can think of send and recv a bit like the BASIC keywords PRINT and INPUT - send will send the data and return immediately (unless the transmit buffer is full), and recv - like INPUT, will block until there's data ready to be returned to the program. There are some other details, too.<br />
<br />
For sending data, we'll assume we've got a buffer somewhere in memory containing the string 'Hello world\n' (i.e. 'Hello world' with a newline), and we want to send this 12-byte chunk of data. In assembler this is what you need to do:<br />
<br />
ld a, (v_connfd) ; file descriptor of the connection we accepted earlier<br />
ld de, BUF_hello ; memory address of the buffer containing 'Hello world\n'<br />
ld bc, 12 ; which is 12 bytes long<br />
ld hl, SEND ; call the SEND function<br />
call HLCALL<br />
jr c, .error ; did it work?<br />
<br />
The ROM call for SEND therefore takes three arguments. The socket file descriptor is passed in the A register. DE contains the address of the block of data to send. BC is set to the number of bytes to send. When SEND returns, if all is well, BC is set to the number of bytes actually sent.<br />
<br />
The C library call is essentially the same, with just one extra parameter, ''flags'' (which currently should be left set to 0).<br />
<br />
char *hstring="Hello world\n";<br />
...<br />
bytes=send(connfd, hstring, strlen(hstring), 0);<br />
<br />
A negative value is returned in case of an error, but otherwise, send returns the number of bytes sent.<br />
<br />
The recv call is very similar - again, it takes the socket on which to receive data, an address of a buffer (in this case, the address of a block of memory to fill), and the size of the buffer. It returns how many bytes were actually received. Note that recv doesn't attempt to fill the entire buffer you give it - the size of the buffer is just the maximum amount of data it will return. If some data that's less than the size of the buffer is received, recv returns this - so it's important to check the number of bytes returned in case you expect more than you actually got! The recv call will block until some data is received. (How to stop your program from stopping until someone sends some data will be covered in the multiplexing tutorial).<br />
<br />
In assembler, recv is used like this:<br />
<br />
ld a, (v_connfd) ; Get the connection file descriptor.<br />
ld de, BUF_receive ; Set DE to the address of a buffer to fill with data<br />
ld bc, 512 ; The buffer pointed to by DE is 512 bytes long.<br />
ld hl, RECV ; Call the RECV function.<br />
call HLCALL ; ...and BC will contain the number of bytes actually received<br />
jr c, .error<br />
<br />
As with send, the RECV function takes three arguments: A contains the socket file descriptor, the DE register pair contains the address off the start of a buffer in memory to fill, and BC contains the maximum amount of data that RECV should put in this buffer. On return, the BC register pair contains the number of bytes actually received, which in many cases will probably be less than the size of the buffer.<br />
<br />
The C call is similar, too:<br />
<br />
char buf[512]; /* allocate a 512 byte buffer */<br />
....<br />
bytes=recv(connfd, buf, sizeof(buf), 0);<br />
<br />
Again, the ''flags'' parameter should be set to zero. If an error occurs, recv returns a negative value.<br />
<br />
=== Closing the connection ===<br />
<br />
Once you're done with a socket, it should be closed. It's important to explicitly do this - while in Unix or Windows, all file descriptors and memory gets cleaned up when a program exits, the Spectrum doesn't really have this concept - so if your program is going to get invoked multiple times, it's important to make sure all sockets are closed when it exits. Many programs will need to service many connections that come and go, for example, a web server will have to open, service and close perhaps dozens of connections a second. Even on a big mainframe, if you didn't clean up the socket file descriptors you could end up running out.<br />
<br />
The close routine does this. If your server is going to be servicing more connections, the original socket should be left open, since this is the one you're listening on, and just the connection sockets should be closed when they are done with (except, of course, when your program exits, at which point you'll want to close your listening socket, too). The close routine is very simple:<br />
<br />
ld a, (v_connfd) ; get the connection's file descriptor<br />
ld hl, CLOSE<br />
call HLCALL<br />
jr c, .error<br />
<br />
So what errors can happen on close? If your program has a bug, you might end up trying to close a socket file descriptor that doesn't actually exist.<br />
<br />
The C close routine is called sockclose. This is because the Z88DK doesn't yet have a truly generalized fcntl, so the z88dk close() routine doesn't know how to close a socket. The sockclose routine, therefore, only works on socket file descriptors and not, say, a file descriptor for a file on disc. This may well change; the z88dk developers are working on a more generalized fcntl right now.<br />
<br />
In C, closing a socket is as simple as:<br />
<br />
if(sockclose(connfd) < 0)<br />
{<br />
handle_error();<br />
return;<br />
}<br />
<br />
== In summary ==<br />
<br />
As you've seen, a simple TCP server consists of creating the socket with the '''[[socket]]''' routine, binding it to a port with '''[[bind]]''', telling it to listen with '''[[listen]]''', accepting an incoming connection with '''[[accept]]''', then sending and receiving data with '''[[send]]''' and '''[[recv]]'''. Once the connection's done, it's closed with '''[[close]]''', or '''[[sockclose]]''' if you're using the z88dk. Both accept and recv block until they get a connection and data respectively, but there are ways to avoid blocking - which will be discussed in a later tutorial.<br />
<br />
In the next tutorial, we'll cover writing a TCP client.<br />
<br />
[[Spectranet: Tutorial 3]]<br />
<br />
== Further reading ==<br />
<br />
Practical code: The simple loader tool, from the utility ROM's NMI menu, which is a simple server that receives data on port 2000 and puts this data into the Spectrum's RAM: [http://spectrum.alioth.net/svn/filedetails.php?repname=Spectranet&path=%2Ftrunk%2From%2Futilnmi.asm] - see the F_loader routine.<br />
<br />
Reference manuals for the functions used:<br />
<br />
* [[socket]]<br />
* [[bind]]<br />
* [[listen]]<br />
* [[accept]]<br />
* [[send]]<br />
* [[recv]]<br />
* [[close]]<br />
<br />
[[Category:Spectranet]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Spectramin&diff=389Spectramin2013-01-26T20:09:47Z<p>Winston: /* The theremin to digital interface */</p>
<hr />
<div>The Spectramin is a just-for-fun project to make a theremin that drives the AY chip in a 128K Spectrum. The interface card is a [[ZX Breakout]] board, using an XC95144 CPLD. The interface provides three channels (all of them essentially 12 bit counters, to read the frequency of the theremin oscillators). As such it'll be really a theremin synthesiser, using the AY chip to make sounds other than the sine wave most theremins make. It might offend purists, since it'll have a foot pedal as a 3rd channel (so that volume, effects and pitch can all be controlled simultaneously).<br />
<br />
It's planned that it'll be ready for the next VCF-GB which will be held within the Silicon Dreams festival, near Ashby-de-la-Zouch in the summer of 2013.<br />
<br />
Browse SVN: [http://spectrum.alioth.net/svn/listing.php?repname=Spectramin&path=%2F& Spectramin SVN]<br />
<br />
== General description ==<br />
<br />
The Spectramin consists of two major parts: the theremin part (which is actually two theremins, one for each hand - in a traditional theremin, one controls pitch and the other volume), and the Spectrum interface part. It departs a little from the traditional theremin, in that there are actually three channels.<br />
<br />
The two theremins make channel 1 and 2. They'll either both be used for pitch for two simultaneous tones, or one for pitch and the other for effects depth. The third channel is a foot pedal (and yes, I know theremin purists will hate that, but tough, I need three channels and I don't have three hands). The foot pedal will be used for volume. Basically, all three channels are audio frequency oscillators, and the interface to the Spectrum is a frequency counter so that the Spectrum may read a value depending on the frequency. (The high resolution frequency counter is 12 bits). The theremins work in the traditional way, the player's hand forming part of the capacitance of the theremin's frequency generating circuit, and the foot pedal is basically a resistor in a multivibrator circuit, determining its output frequency. Since the Spectrum's power supply circuit is obscenely noisy, the theremin circuits and footpedal circuit operate from an independent power supply (a battery, since that's a very clean and stable power source - however, a regulated linear power supply should also work), and are optoisolated from the Spectrum's noisy digital circuits.<br />
<br />
The Spectrum interface is implemented in a Xilinx XC95144XL CPLD. This provides three 12-bit frequency counters (plus an 8 bit low resolution read for the user interface displays), as well as a push button interface so that I can add some foot operated buttons to do things such as change instrument.<br />
<br />
== The theremin to digital interface ==<br />
<br />
The theremin circuits output an analogue wave form (a pretty good approximation of a sine wave) with an amplitude of about 600mV. The box will have a jack so the analogue output can also be used for more traditional theremin use by connecting it straight to an amplifier, but internally this analogue wave will be turned into a rail-to-rail square wave by an op-amp circuit. The output of this gets fed to the optoisolator, and from there goes to the Spectrum.<br />
<br />
== The foot pedal interface ==<br />
<br />
This uses the remaining two op-amps in the CMOS quad op-amp used by the theremin to digital interface. One op-amp provides a reference voltage halfway between ground and the supply to provide the "ground" for a simple multivibrator circuit (basically [http://hyperphysics.phy-astr.gsu.edu/hbase/electronic/square.html#c2 this one here], the foot pedal goes between R1 and ground). The output of this is a square wave, and it's fed to the optoisolator.<br />
<br />
[[Category:Spectramin]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Spectramin&diff=388Spectramin2013-01-26T20:08:17Z<p>Winston: </p>
<hr />
<div>The Spectramin is a just-for-fun project to make a theremin that drives the AY chip in a 128K Spectrum. The interface card is a [[ZX Breakout]] board, using an XC95144 CPLD. The interface provides three channels (all of them essentially 12 bit counters, to read the frequency of the theremin oscillators). As such it'll be really a theremin synthesiser, using the AY chip to make sounds other than the sine wave most theremins make. It might offend purists, since it'll have a foot pedal as a 3rd channel (so that volume, effects and pitch can all be controlled simultaneously).<br />
<br />
It's planned that it'll be ready for the next VCF-GB which will be held within the Silicon Dreams festival, near Ashby-de-la-Zouch in the summer of 2013.<br />
<br />
Browse SVN: [http://spectrum.alioth.net/svn/listing.php?repname=Spectramin&path=%2F& Spectramin SVN]<br />
<br />
== General description ==<br />
<br />
The Spectramin consists of two major parts: the theremin part (which is actually two theremins, one for each hand - in a traditional theremin, one controls pitch and the other volume), and the Spectrum interface part. It departs a little from the traditional theremin, in that there are actually three channels.<br />
<br />
The two theremins make channel 1 and 2. They'll either both be used for pitch for two simultaneous tones, or one for pitch and the other for effects depth. The third channel is a foot pedal (and yes, I know theremin purists will hate that, but tough, I need three channels and I don't have three hands). The foot pedal will be used for volume. Basically, all three channels are audio frequency oscillators, and the interface to the Spectrum is a frequency counter so that the Spectrum may read a value depending on the frequency. (The high resolution frequency counter is 12 bits). The theremins work in the traditional way, the player's hand forming part of the capacitance of the theremin's frequency generating circuit, and the foot pedal is basically a resistor in a multivibrator circuit, determining its output frequency. Since the Spectrum's power supply circuit is obscenely noisy, the theremin circuits and footpedal circuit operate from an independent power supply (a battery, since that's a very clean and stable power source - however, a regulated linear power supply should also work), and are optoisolated from the Spectrum's noisy digital circuits.<br />
<br />
The Spectrum interface is implemented in a Xilinx XC95144XL CPLD. This provides three 12-bit frequency counters (plus an 8 bit low resolution read for the user interface displays), as well as a push button interface so that I can add some foot operated buttons to do things such as change instrument.<br />
<br />
== The theremin to digital interface ==<br />
<br />
The theremin circuits output an analogue wave form (a pretty good approximation of a sine wave) with an amplitude of about 600mV. The box will have a jack so the analogue output can also be used for more traditional theremin use, but internally this analogue wave will be turned into a rail-to-rail square wave by an op-amp circuit. The output of this gets fed to the optoisolator, and from there goes to the Spectrum.<br />
<br />
== The foot pedal interface ==<br />
<br />
This uses the remaining two op-amps in the CMOS quad op-amp used by the theremin to digital interface. One op-amp provides a reference voltage halfway between ground and the supply to provide the "ground" for a simple multivibrator circuit (basically [http://hyperphysics.phy-astr.gsu.edu/hbase/electronic/square.html#c2 this one here], the foot pedal goes between R1 and ground). The output of this is a square wave, and it's fed to the optoisolator.<br />
<br />
[[Category:Spectramin]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=387Main Page2013-01-20T12:06:18Z<p>Winston: </p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! They are sold via [http://www.sellmyretro.com/offer/details/*BRAND_NEW*_Sinclair_ZX_Spectrum_Spectranet_%28Ethernet_add-on%29-2511 RWAP Software] (who also sells other useful items like replacement keyboard membranes). The Spectranet is also available from the RWAP Software stand at retro events.<br />
<br />
WebSVN has been set up so that the Spectranet repository can be browsed and downloaded easily: see http://spectrum.alioth.net/svn .<br />
<br />
'''Latest Spectranet firmware''': R554 (released 19th Jan 2013)<br />
<br />
'''New!''' [[ZX Breakout]] allows CPLD development and easy access to ZX bus signals on a pin header.<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Spectramin]] - Spectrum 128K AY theremin<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
* [[SpectraDVI]] - A digital video ULA+ add-on for the Spectrum?<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [http://spectrum.alioth.net/svn WebSVN] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Spectrum:Current_events&diff=386Spectrum:Current events2013-01-20T12:03:45Z<p>Winston: Redirected page to Current events</p>
<hr />
<div>#REDIRECT [[Current_events]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Spectrum:Current_events&diff=385Spectrum:Current events2013-01-20T12:03:28Z<p>Winston: Redirected page to Current Events</p>
<hr />
<div>#REDIRECT [[Current Events]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Gebrauchsanweisung&diff=384Gebrauchsanweisung2013-01-20T11:54:24Z<p>Winston: Created page with "== Start == Welchen Spectrum hast Du? Wenn Du einen 48K, Spectrum+, 128K mit Heatsink oder einen grauen +2 hast, stelle sicher, dass der Jumper J3 entfernt ist (der Jumper der..."</p>
<hr />
<div>== Start == <br />
<br />
Welchen Spectrum hast Du?<br />
<br />
Wenn Du einen 48K, Spectrum+, 128K mit Heatsink oder einen grauen +2 hast, stelle sicher, dass der Jumper J3 entfernt ist (der Jumper der am nächsten zum JTAG und Edge Connector ist)<br />
Wenn Du einen +3 oder schwarzen +2 hat muss Jumper J3 gesteckt sein<br />
128K Geräte müssen USR 0 Modus für die BASIC Unterstützung verwenden, was automatisch gestartet wird. Zurzeit sind die BASIC Erweiterungen nicht mit dem 128K Editor kompatibel. (Im USR0 Modus hat man vollen Zugriff auf den 128er Speicher und 128K Spiel funktionieren).<br />
<br />
== Konfiguration ==<br />
<br />
In der Standard-Konfiguration wird DHCP verwendet um ein IP-Adresse zu erhalten. Wenn Du keinen DHCP Server hast oder eine statische Adresse verwenden willst, benutze folgenden Befehl:<br />
<br />
%ifconfig<br />
<br />
Du kannst auch den NMI verwenden um ins Konfigurationsmenü zu gelangen (überbrücke kurz S1 mit etwas metallischen oder bau einen Schalter ein)<br />
<br />
== Konfiguration des Datei System ==<br />
<br />
Du benötigst einen Fileserver (Das „tnfsd“ - ein Installer dafür wird vorbereitet). Es gibt einen öffentlichen Fileserver den Du benutzen kannst: vexed4.alioth.net. Um ein Datei System zu verbinden benutze den %mount Befehl. Zum Beispiel<br />
<br />
%mount 0,"vexed4.alioth.net"<br />
<br />
Vermutlich würdest Du das gerne automatisch machen. Du kannst die automatische Verbindung mit diesem Befehl einrichten<br />
<br />
%fsconfig<br />
<br />
Folgendes Menü erscheint:<br />
<br />
[[Image:Fsconfig.jpg|thumb|600px|center]]<br />
<br />
Drücke „A“ um ein neues Dateisystem hinzuzufügen – zum Beispiel um „tnfs://vexed4.alioth.net“ als das Standard-Dateisystem hinzufügen:<br />
<br />
* Drücke „A“ – Set a filesystem<br />
* Drücke „0“ und Enter um Dateisystem #0 auszuwählen<br />
* Gib‘ tnfs://vexed4.alioth.net ein<br />
* Drücke D um die Änderungen zu Speichern<br />
<br />
Wenn der Spectrum resettet wird, wird der Server „vexed4.alioth.net“ verbunden<br />
<br />
Wenn es Probleme bei der Verbindung mit einem Fileserver gibt (z.B. falls der Fileserver gerade nicht läuft) kannst Du BREAK drücken während der Spectrum versucht die Verbindung herzustellen um den Vorgang abzubrechen.<br />
<br />
== Kurz Anleitung zu den BASIC Befehlen ==<br />
<br />
=== Im Dateisystem bewegen ===<br />
<br />
==== %mount ====<br />
<br />
%mount <fsnum>,“<url>“ – Ein Dateisystem verbinden. Beispiele:<br />
<br />
%mount 0,"vexed4.alioth.net"<br />
%mount 0,"192.168.0.1"<br />
%mount 1,"tnfs://192.168.0.1"<br />
%mount 3,"tnfs://example.com/games"<br />
<br />
Die URL arbeitet genauso wie man es erwartet. Wenn es es ein Dateisystem für ein DivIDE gibt, wäre der Befehl so etwas wie %mount 0,“ide://0 (oder etwas ziemlich ähnliches).<br />
<br />
==== %umount ====<br />
<br />
%umount <fsnum> - Ein Dateisystem trennen. Beispiele:<br />
<br />
%umount 0<br />
<br />
==== %cat ====<br />
<br />
%cat „<fsp>“ – Zeigt die Inhalte eines Verzeichnisses an. Beispiel:<br />
<br />
%cat<br />
%cat "foobar"<br />
%cat "0:/foo/bar/baz"<br />
<br />
Der Pfad funktioniert wie ein Uniy-Pfad, der Trenner zwischen den Verzeichnissen ist ein „/“. Wie erwartet bedeutet „.“ den aktuellen Pfad und „..“ den übergeordneten Pfad.<br />
<br />
==== %cd ====<br />
<br />
%cd „<fsp>“ – Verzeichnis wechseln. Beispiele:<br />
<br />
%cd "/"<br />
%cd "games"<br />
%cd "/programs/basic"<br />
%cd ".."<br />
<br />
==== %fs ==== <br />
<br />
%fs <fsnum> - Wechsle das Dateisystem<br />
<br />
%fs 1<br />
<br />
Das Standard Dateisystem ist 0.<br />
<br />
=== Lesen und Schreiben von Dateien ===<br />
<br />
==== %load ====<br />
<br />
%load „fsp“ [CODE Adresse] – Eine Datei laden. Beispiele:<br />
<br />
%load "manic"<br />
%load "image" CODE 16384<br />
%load "/foo/bar/baz.zx"<br />
%load ""<br />
<br />
Der Befehl %load „“ würde das BASIC Programm „boot.zx“ laden. (Wenn im %fsconfig Menü die Autoboot-Option ausgewählt wurde, versucht der Spectrum nach einem Reset„0:/boot.zx“ zu laden).<br />
<br />
==== %save ====<br />
<br />
%save „<fsp>“ [CODE Adresse} – Eine Datei speichern. Beispiele:<br />
<br />
%save "program"<br />
%save "image" CODE 16384,6912<br />
%save "program" LINE 1<br />
<br />
==== %aload ====<br />
<br />
%aload „<fsp>“ CODE Adresse – Beliebige Dateien laden. Beispiel:<br />
<br />
%aload "machinecode" CODE 32768<br />
<br />
Der Unterschied zwischen %load und %aload ist das %aload auch Dateien ohne „header“ lädt. Die normalen Dateien sind als TAP Archive formatiert, d.h. sie haben die gleichen „header“ wie Dateien die auf eine Kassette gespeichert werden – sie enthalten die Adresse wohin die Daten geladen werden soll und die Art der Datei – als Beispiel „Program“ oder „Bytes. Der %aload Befehl kann alle Dateien laden. Darum muss man immer die Adresse mit angeben wohin die Datei geladen werden soll, da kein Header vorhanden ist, der die Daten enthält.<br />
<br />
Daher ist %aload notwendig wenn Du eine Datei laden willst die Du am PC erstellt hast (z.B. mit einem Cross Assembler) und die nicht als TAP Datei gespeichert wurde.<br />
<br />
==== %tapein ====<br />
<br />
%tapein „<fsp>“ – Lade eine .TAP Datei. Beispiel:<br />
<br />
%tapein "jsw.tap"<br />
LOAD ""<br />
<br />
%tapein wird benötigt um eine Kassette zu „simulieren“. Danach muss immer LOAD „“ (oder ähnlich) benutzt werden um die virtuelle Kassette tatsächlich zu starten.<br />
<br />
==== %loadsnap ====<br />
<br />
%loadsnap „<fsp>“ – Lade einen .SNA Snaphot. Beispiel:<br />
<br />
%loadsnap "matchday.sna"<br />
<br />
Dieser Befehl arbeitet sowohl mit 48K als auch mit 128K snapshots.<br />
<br />
=== Öffnen und Schließen von Dateien ===<br />
<br />
Es gibt eine Reihe von Befehlen die mit ZX BASIC Streams benutzt werden. Diese arbeiten mit Dateien, Verzeichnissen und Netzwerk Sockets. Hier ein Beispiel und eine kurze Beschreibung:<br />
<br />
10 %open #4,"file","r"<br />
20 %oneof 100<br />
30 INPUT #4,a$<br />
40 PRINT a$<br />
50 GO TO 30<br />
100 %close #4<br />
<br />
Dieses Programm öffnet eine Datei mit Namen „file“, liest die Inhalte und gibt diese am Bildschirm aus. Die erste Zeile:<br />
<br />
10 %open #4,"file","r"<br />
<br />
Öffnet die Datei mit Namen „file“ zum Lesen. Zeile 20 ist für die End-Of-Life Bedingung. Sie bedeutet das zu Zeile 100 gesprungen wird wenn ein EOF angetroffen wird. Zeile 30, 40 und 50 sind Standard ZX BASIC Befehle um den Datenstrom zu lesen und die Ergebnisse am Bildschirm anzuzeigen. Endlich wird Zeile 100 erreicht wo die Datei geschlossen wird. (Es ist sehr wichtig dass das gemacht wird!).<br />
<br />
=== Öffnen und Schließen von Sockets ===<br />
<br />
Es ist sehr einfach mit einer Netzwerkverbindung ähnliche Sachen zu machen. Zum Beispiel:<br />
<br />
10 %connect #4,"spectrum.alioth.net",80<br />
20 %oneof 100<br />
30 PRINT #4;"GET HTTP/1.0"<br />
40 PRINT #4<br />
50 INPUT #4;a$<br />
60 PRINT a$<br />
70 GO TO 50<br />
100 %close #4<br />
<br />
Mit Code der sehr ähnlich zum ersten Beispiel ist, kann man sich zu einer anderen Maschine verbinden wenn man ein TCP Socket benutzt. Der Syntx von %connect lautet:<br />
<br />
%connect #<stream>,"address",port<br />
<br />
Hier ein sehr einfaches Beispiel ein in BASIC geschriebenen Servers:<br />
<br />
10%listen #4,2000<br />
20%accept #5,4<br />
30 INPUT #5;a$<br />
40 PRINT #5;"You sent me: ";a$<br />
60%close #5<br />
70%close #4<br />
<br />
Du kannst das von einem PC aus versuchen indem Du „telnet“ benutzt:<br />
<br />
telnet <ip-address-of-spectrum> 2000<br />
<br />
Zum Beispiel:<br />
<br />
serendipity:~ winston$ telnet 172.16.0.41 2000<br />
Trying 172.16.0.41...<br />
Connected to 172.16.0.41.<br />
Escape character is '^]'.<br />
hello<br />
You sent me: hello<br />
Connection closed by foreign host.<br />
<br />
Ein komplexeres Beispiel: ein Server der bis zu 3 gleichzeitige Verbindungen handeln kann auf Port 2000:<br />
<br />
1 DIM c(4)<br />
10%listen #4,2000<br />
20%control #5<br />
30 PRINT #5;"p"<br />
40 PRINT "Waiting..."<br />
45 INPUT #5;a;a$<br />
50 IF a<>0 THEN GO TO 200<br />
60 LET a$=INKEY$<br />
70 IF a$="x" THEN GO TO 700<br />
80 GO TO 45<br />
200 IF a=4 THEN GO TO 400<br />
210 IF a$="disconn" THEN GO TO 600<br />
220 INPUT #a;c$<br />
230 PRINT "Strm ";a;": ";c$<br />
240 IF c$="rnd" THEN PRINT #a;RND: GO TO 40<br />
250 IF c$="foo" THEN PRINT a;"Foo bar baz": GO TO 40<br />
260 IF c$="quit" THEN PRINT #a;"Adios":GO TO 600<br />
300 PRINT #a;"I didn't understand that"<br />
310 GO TO 40<br />
400 FOR i=1 TO 4<br />
410 IF c(i)=0 THEN LET chan=i+5: GO TO 500<br />
420 NEXT i<br />
430 PRINT "Out of streams"<br />
440 STOP<br />
500 PRINT "Accepted connection on stream ";chan<br />
510%accept #chan,4<br />
520 LET c(i)=1<br />
530 GO TO 40<br />
600 PRINT "Closing #";a<br />
605%close #a<br />
610 LET c(a-5)=0<br />
620 GO TO 40<br />
700 PRINT "The program has finished"<br />
710%close #5<br />
715 PRINT "Closing socket"<br />
720%close #4<br />
730 PRINT "Closing connections"<br />
740 FOR i=1 TO 4<br />
750 IF c(i)=1 THEN %close #i+5<br />
760 NEXT i<br />
<br />
Um es vom PC zu versuchen verwende „telnet <ip-vom-spectrum> 2000. Du kannst „rnd“, „quit“ oder „foo“ eintippen.<br />
<br />
Erwähnenswerte Teile des Programms:<br />
<br />
10 %listen #4,"2000"<br />
<br />
Wenn diese Zeile ausgeführt wird beginnt der Spectrum Port 2000 (tcp) zu überwachen. Wenn eine Verbindung ankommt muss noch etwas erledigt werden: sie muss akzeptiert werden. Dafür wird der %accept Befehl benutzt. Jedoch blockiert %accept das Warten auf eine Verbindung (in anderen Worten: die Ausführung des Programms wird während des Wartens gestoppt). Um ohne Warten fortfahren zu können, gibt es einen Control Channel, der es erlaubt den Status des Socket zu überwachen. Er wird so geöffnet:<br />
<br />
20 %control #5<br />
<br />
Nun ist Stream #5 der Control Channel. Man kann in dem Stream so schreiben und lesen:<br />
<br />
30 PRINT #5;"p"<br />
50 INPUT #5;a;a$<br />
<br />
Zeile 30 sagt dem Control Channel “erzähle mir ob an einem Socket Daten warten“ (das schließt Sockets ein die im „Hören“-Status sind. In Zeile 50 kommen 2 Dinge an: Die Stream Nummer auf welchem Daten bereit stehen und Info über die Art der Daten (Daten die zur Verfügung stehen kann eine Verbindung sein die akzeptiert werden soll, das beenden einer Verbindung oder nur Buchstaben zum Lesen). Wenn der Stream #4 ist, wissen wir das es eine neue Verbindung sein muss die akzeptiert werden soll weil Stream 4 der Port ist der „zuhört“. Wenn die Variable A eine 0 enthält hat kein Socket wartende Daten.<br />
<br />
510 %accept #chan,4<br />
<br />
In dieser Zeile akzeptieren wir schließlich eine neue Verbindung. Der %accept Befehl akzeptiert die Verbindung und erstellt einen neuen Stream für Daten die in dieser Verbindung gelesen und geschrieben werden. Die Syntax von %accept lautet:<br />
<br />
%accept #stream,listening-stream<br />
<br />
Stream 4 ist der zuhörende Stream in diesem Fall. Die Variable #chan ist die Nummer des neuen Stream der geöffnet werden soll.<br />
<br />
=== Maschinen Code === <br />
<br />
Wenn Du Programme in C schreiben willst, gibt es einen Guide mit Beispielen. Sockets werden auf die gleiche Weise benutzt wie in Unix oder Windows – wenn Du bereits weißt wie man Netzwerkprogramme für moderne Betriebssystem schreibt wirst Du keine Probleme haben. Wenn Du noch nie die BSD Socket Library verwendet hast – dafür gibt es Tutorials.<br />
<br />
[[Software|Die Anleitung ist hier]] (English)<br />
<br />
[[Category:Spectranet]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=383Main Page2013-01-20T11:42:47Z<p>Winston: /* Project Info */</p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! The first boards will be available from the RWAP Software stand at Spectrum30 in Cambridge. Additionally, WebSVN has been set up so that the Spectranet repository can be browsed and downloaded easily: see http://spectrum.alioth.net/svn .<br />
<br />
'''Latest Spectranet firmware''': R554 (released 19th Jan 2013)<br />
<br />
'''New!''' [[ZX Breakout]] allows CPLD development and easy access to ZX bus signals on a pin header.<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Spectramin]] - Spectrum 128K AY theremin<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
* [[SpectraDVI]] - A digital video ULA+ add-on for the Spectrum?<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español [[Gebrauchsanweisung]] Deutsch - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [http://spectrum.alioth.net/svn WebSVN] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Spectramin&diff=382Spectramin2013-01-19T18:21:11Z<p>Winston: Created page with "The Spectramin is a just-for-fun project to make a theremin that drives the AY chip in a 128K Spectrum. The interface card is a ZX Breakout board, using an XC95144 CPLD. The ..."</p>
<hr />
<div>The Spectramin is a just-for-fun project to make a theremin that drives the AY chip in a 128K Spectrum. The interface card is a [[ZX Breakout]] board, using an XC95144 CPLD. The interface provides three channels (all of them essentially 12 bit counters, to read the frequency of the theremin oscillators). As such it'll be really a theremin synthesiser, using the AY chip to make sounds other than the sine wave most theremins make. It might offend purists, since it'll have a foot pedal as a 3rd channel (so that volume, effects and pitch can all be controlled simultaneously).<br />
<br />
It's planned that it'll be ready for the next VCF-GB which will be held within the Silicon Dreams festival, near Ashby-de-la-Zouch in the summer of 2013.<br />
<br />
Browse SVN: [http://spectrum.alioth.net/svn/listing.php?repname=Spectramin&path=%2F& Spectramin SVN]<br />
<br />
[[Category:Spectramin]]</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=Main_Page&diff=381Main Page2013-01-19T18:16:38Z<p>Winston: </p>
<hr />
<div>== Downloads ==<br />
<br />
Get the latest files - including fileserver software so you can share files from your PC to the Spectrum - from the downloads section:<br />
<br />
* [[Downloads]] - PC software, ROM images, utilities etc.<br />
<br />
== Latest News ==<br />
<br />
The Spectranet has reached "general availability"! The first boards will be available from the RWAP Software stand at Spectrum30 in Cambridge. Additionally, WebSVN has been set up so that the Spectranet repository can be browsed and downloaded easily: see http://spectrum.alioth.net/svn .<br />
<br />
'''Latest Spectranet firmware''': R554 (released 19th Jan 2013)<br />
<br />
'''New!''' [[ZX Breakout]] allows CPLD development and easy access to ZX bus signals on a pin header.<br />
<br />
See [[Current_events|the news blog]] for more.<br />
<br />
== Project Info ==<br />
<br />
* [[Spectramin]] - Spectrum 128K AY theremin<br />
* [[ZX Breakout]] - Provides ZX bus signals on a header, and a CPLD for logic functions. Also allows 3.3v devices to be used with the Spectrum.<br />
* [[SpectraDVI]] - A digital video ULA+ add-on for the Spectrum?<br />
* [[Spectranet]] - The Spectrum ethernet card - make your Spectrum talk to the world.<br />
** [[Guide]] (English) [[Guía]] Español - Quick guide for new users.<br />
** [http://fuse-emulator.svn.sourceforge.net/viewvc/fuse-emulator/trunk/fuse/hacking/spectranet.txt FUSE users - setting up the Spectranet] Setting up the Spectranet on the development version of the Fuse emulator.<br />
** [[Downloads]] - ROM images, utilities etc.<br />
** [[Hardware]] - A reference for the details of the hardware used for the Spectranet board.<br />
** [[Software|Software development]] - A reference for writing software that uses the Spectranet.<br />
** [http://spectrum.alioth.net/svn WebSVN] - Browse the Spectranet source code.<br />
* [http://www.alioth.net/Projects/Spectrum-Diag/ Diagnostics] - A simple diagnostics card - assists in fixing broken machines.<br />
<br />
== Tools ==<br />
<br />
The software tools used for all of these projects are:<br />
<br />
* gschem: http://www.geda.seul.org/tools/gschem/ - gEDA Schematic Capture.<br />
* PCB: http://pcb.sourceforge.net/ - PCB editor.<br />
* Xilinx WebKit ISE - for configuring the CPLD. http://www.xilinx.com<br />
<br />
Gerber files and PostScript files will also be available, so if you don't want to edit the PCB layouts or schematics, you can produce the phototools/toner transfer sheets without needing them. You will need at least the Impact part of ISE to program a CPLD. Programming hardware can be as simple as a parallel cable since Xilinx CPLDs are programmed via JTAG rather than some byzantine high voltage programming method.</div>Winstonhttps://spectrum.alioth.net/doc/index.php?title=ZX_Breakout&diff=380ZX Breakout2013-01-19T18:14:08Z<p>Winston: </p>
<hr />
<div>[[Image:Zxbreakout1.jpg|thumb|right|500px|ZX Breakout with XC95144XL]]<br />
<br />
This is a CPLD (complex programmable logic device) breakout board for the Spectrum (including 128K and Amstrad models). The original idea behind this board was to provide a breakout board for the ZX Spectrum bus signals, and also level shifting of all the signals to 3.3v with a second set of breakout pins. This was to provide an interface to chips that are not 5v tolerant, such as all current in-production FPGAs.<br />
<br />
Using a CPLD instead of simple level shifters does two things: it provides the original functionality of a breakout board with a level shifter since a 3.3v CPLD with 5v tolerant IO can be used for this purpose, and for prototyping or making the logic for other things too - in other words, make a versatile breakout board for both the ZX bus and a CPLD.<br />
<br />
Either the Xilinx XC9572XL or the XC95144XL CPLD can be used on this board. To give a rough idea of the logic resources these CPLDs provide, Chris Smith's timing accurate ULA replacement fills an XC95144XL, that's to say this CPLD has a similiar amount of resource to the Spectrum ULA.<br />
<br />
=== Errata ===<br />
Due to a dumb mistake, the ROMCS circuit is incorrect for the black +2 and +3 machines. If you intend to use the ZX Breakout with one of these, a simple workaround is to just not connect pin 4 of the edge connector (top side, 4th pin from the left) or desolder it if you've already connected it. The board will not work at all with a black +2 or +3 unless you do this, even if you're not planning to use ROMCS. It works fine with all other models as-is.<br />
<br />
== The board ==<br />
<br />
[[Image:Zxbreakout.png|thumb|right|500px|ZX Breakout PCB]]<br />
<br />
The PCB features the following:<br />
<br />
* All major ZX bus digital signals routed to the CPLD.<br />
* Header for ZX signals, nearest the Spectrum edge connector.<br />
* 3.3v linear power supply for the CPLD.<br />
* JTAG header for programming the CPLD.<br />
* Ability to control the ROMCS line.<br />
* Clock is inverted (to be in phase with the CPU clock) by a Schmitt-trigger buffer giving sharper rising and falling edges.<br />
* Two headers for CPLD signals - a 40 pin header with 32 CPLD general purpose IOs, and a 10 pin header with 7 general purpose IOs.<br />
* 40 pin header laid out with ground and power pins in the same location as an IDE connector.<br />
* 4 layer PCB with solid ground and power planes for ideal CPLD performance.<br />
<br />
Additionally, the ZX signals and CPLD pin locations are shown in the silk screen, so you know what you're connecting to without having to reach for a datasheet.<br />
<br />
== Pin locations ==<br />
<br />
=== ZX bus to CPLD ===<br />
<br />
ZX bus function to CPLD function block mapping is optimized for the XC9572, being the smallest device with fewest resources. For the '72, the data bus and upper half of the address bus is grouped into function block 1, and the lower half of the address bus and control signals in function block 3. The remaining pins go to the GPIO headers.<br />
<br />
The ZX clock is mapped to a global clock signal, and the reset signal is inverted and buffered and routed to the global system reset pin. A global clock signal is available on the GPIO header.<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"| ZX signal<br />
! CPLD pin<br />
! XC9572 FB<br />
! XC95144 FB<br />
! Comments<br />
|- <br />
|D0||18||1||1||<br />
|- <br />
|D1||20||1||1||<br />
|-<br />
|D2||22||1||1||<br />
|- <br />
|D3||29||1||3||<br />
|-<br />
|D4||30||1||3||<br />
|- <br />
|D5||28||1||3||<br />
|-<br />
|D6||25||1||3||<br />
|- <br />
|D7||17||1||1||<br />
|-<br />
|A0||32||3||3||<br />
|- <br />
|A1||35||3||5||<br />
|-<br />
|A2||37||3||5||<br />
|- <br />
|A3||41||3||5||<br />
|-<br />
|A4||59||3||7||<br />
|- <br />
|A5||58||3||7||<br />
|-<br />
|A6||56||3||7||<br />
|- <br />
|A7||55||3||7||<br />
|-<br />
|A8||40||1||5||<br />
|- <br />
|A9||39||1||5||<br />
|-<br />
|A10||36||1||5||<br />
|- <br />
|A11||33||1||3||<br />
|-<br />
|A12||15||1||1||<br />
|- <br />
|A13||16||1||1||<br />
|-<br />
|A14||13||1||1||<br />
|- <br />
|A15||14||1||1||<br />
|-<br />
|/MREQ||50||3||7||<br />
|- <br />
|/IORQ||52||3||7||<br />
|-<br />
|/RD||53||3||7||<br />
|- <br />
|/WR||54||3||7||<br />
|-<br />
|/M1||60||3||7||<br />
|- <br />
|/INT||42||3||5||<br />
|-<br />
|/NMI||49||3||5||<br />
|-<br />
|CLK||23||1||5||Buffered; CPLD GCK2<br />
|-<br />
|RESET||99||2||3||Buffered; CPLD GSR (active high)<br />
|-<br />
|ROMCS||61||3||7||Only when "Use ROMCS" is jumpered<br />
|-<br />
|}<br />
<br />
=== 40 pin header ===<br />
<br />
The 40 pin header is numbered using the ribbon cable style of numbering. Pin 1 is at the top right hand side of the connector, when looking down at the component side of the PCB, with the ZX edge connector at the bottom (in other words, as shown in the image on this page).<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"| Header pin<br />
! CPLD pin<br />
! XC9572 FB<br />
! XC95144 FB<br />
! Comments<br />
|- <br />
|1||68||4||8||<br />
|- <br />
|2||GND||||||<br />
|-<br />
|3||71||4||8||<br />
|-<br />
|4||70||4||8||<br />
|-<br />
|5||74||4||6||<br />
|-<br />
|6||72||4||8||<br />
|-<br />
|7||77||4||6||<br />
|-<br />
|8||76||4||6||<br />
|-<br />
|9||79||4||6||<br />
|-<br />
|10||78||4||6||<br />
|-<br />
|11||82||4||6||<br />
|-<br />
|12||81||4||6||<br />
|-<br />
|13||86||4||6||<br />
|-<br />
|14||85||4||6||<br />
|-<br />
|15||89||4||4||<br />
|-<br />
|16||87||2||4||<br />
|-<br />
|17||91||2||4||<br />
|-<br />
|18||90||4||4||<br />
|-<br />
|19||GND||||||<br />
|-<br />
|20||3.3v||||||<br />
|-<br />
|21||92||2||4||<br />
|-<br />
|22||GND||||||<br />
|-<br />
|23||93||2||4||<br />
|-<br />
|24||GND||||||<br />
|-<br />
|25||94||2||4||<br />
|-<br />
|26||GND||||||<br />
|-<br />
|27||95||2||4||<br />
|-<br />
|28||96||2||4||<br />
|-<br />
|29||97||2||4||<br />
|-<br />
|30||GND||||||<br />
|-<br />
|31||1||2||2||<br />
|-<br />
|32||3||2||2||GTS1<br />
|-<br />
|33||4||2||2||GTS2<br />
|-<br />
|34||6||2||2||<br />
|-<br />
|35||8||2||2||<br />
|-<br />
|36||9||2||2||<br />
|-<br />
|37||10||2||2||<br />
|-<br />
|38||11||2||1||<br />
|-<br />
|39||12||2||1||<br />
|-<br />
|40||GND||||||<br />
|-<br />
|}<br />
<br />
=== 10 pin header ===<br />
<br />
This header uses ribbon cable numbering, with pin 1 being the top left pin looking down on the PCB, as in the image above.<br />
<br />
Pin 4 is the same as the ROMCS pin on the header next to the edge connector - it's just a straight connection. It is provided as an alternative site to connect a wire to ROMCS. Pin 9 is not connected to the CPLD if the "Use ROMCS" jumper is closed. When this jumper is closed, CPLD pin 61 will go to the transistor controlling the ROMCS line allowing the CPLD to page out the ZX ROM. Pin 10 routes to a global clock pin, it may also be used as general purpose IO.<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"| Header pin<br />
! CPLD pin<br />
! XC9572 FB<br />
! XC95144 FB<br />
! Comments<br />
|- <br />
|1||3.3v||||||<br />
|-<br />
|2||GND||||||<br />
|-<br />
|3||67||4||8||<br />
|-<br />
|4||ROMCS||||<br />
|-<br />
|5||66||4||8||<br />
|-<br />
|6||65||4||8||<br />
|-<br />
|7||64||3||8||<br />
|-<br />
|8||63||3||8||<br />
|-<br />
|9||61||3||7||May be routed to ROMCS<br />
|-<br />
|10||27||1||3||GCK3<br />
|-<br />
|}<br />
<br />
== Xilinx UCF file for pins ==<br />
<br />
Copy and paste this into your UCF text constraints file for the list of pins. Comment out the signals you aren't using with a # in front of that line (ISE will fail at the fitter stage if you have nets defined in your UCF file which don't exist in your design). Signals with "_L" at the end are active low. Note that RESET is active high (it's been inverted). This is generally what you want; the Xilinx library components all have active high reset. The clock is also in phase with the Z80 clock.<br />
<br />
Also note that the pin used to control ROMCS can also be used as a GPIO, depending on the position of the jumper. ROMCS is active low from the point of view of the CPLD.<br />
<br />
This file will also appear in Subversion.<br />
<br />
GPIO pins are not listed in this file since you'll be defining them according to whatever function they may have.<br />
<br />
net A(0) loc=p32;<br />
net A(1) loc=p35;<br />
net A(2) loc=p37;<br />
net A(3) loc=p41;<br />
net A(4) loc=p59;<br />
net A(5) loc=p58;<br />
net A(6) loc=p56;<br />
net A(7) loc=p55;<br />
<br />
net A(8) loc=p40;<br />
net A(9) loc=p39;<br />
net A(10) loc=p36;<br />
net A(11) loc=p33;<br />
net A(12) loc=p15;<br />
net A(13) loc=p16;<br />
net A(14) loc=p13;<br />
net A(15) loc=p14;<br />
<br />
net D(0) loc=p18;<br />
net D(1) loc=p20;<br />
net D(2) loc=p22;<br />
net D(3) loc=p29;<br />
net D(4) loc=p30;<br />
net D(5) loc=p28;<br />
net D(6) loc=p25;<br />
net D(7) loc=p17; <br />
<br />
net MREQ_L loc=p50;<br />
net IORQ_L loc=p52;<br />
net RD_L loc=p53;<br />
net WR_L loc=p54;<br />
net M1_L loc=p60;<br />
net INT_L loc=p42;<br />
net NMI_L loc=p49; <br />
<br />
net CLK loc=p23;<br />
net RESET loc=p99;<br />
<br />
net ROMCS_L loc=p61;<br />
<br />
== Components used ==<br />
<br />
{| class="wikitable" style="text-align: center; color: green;"<br />
! align="left"|Refdes<br />
! Component<br />
! Package<br />
! Mfr.<br />
! Description<br />
! Notes<br />
|- <br />
|U1||P565D2T33||D2PAK3||ON Semi||3.3v LDO regulator||<br />
|-<br />
|U2||74HCT14||SOIC 14||Any||Schmitt trigger inverter, TTL compatible||<br />
|-<br />
|U3||XC9572XL||TQFP 100||Xilinx||CPLD||Use XC95144XL for more logic resources<br />
|-<br />
|C1, C2||150uF||Tant B||Any||Capacitor||<br />
|-<br />
|C3||1uF||1206||Any||Capacitor||<br />
|-<br />
|C4 to C10||0.1uF||0603||Any||Capacitor||<br />
|-<br />
|R1||300R||0603||Any||Resistor||<br />
|-<br />
|Q1||BSS84P||SOT23||Infineon||P channel MOSFET||<br />
|-<br />
|}<br />
<br />
ZX bus edge connector is an open ended 28 position 0.1 inch pitch connector, with position 5 contacts removed and replaced with a plastic key. This connector usually needs to be hand made by cutting down a larger connector (such as an old ISA bus connector).<br />
<br />
40 pin, 10 pin and 60 pin headers are up to the board's user. It's suggested that SIL sockets are used for the headers since this allows wires to be plugged in and connected to a breadboard etc. However, if a ribbon cable is to be used, a PCB to ribbon connector is recommended.<br />
<br />
It is suggested that normal jumper pin headers are used for the jumpers.<br />
<br />
[[Category:ZX Breakout]]</div>Winston