RetroChallenge 2016/10 – One bodge to fix them all

It’s two days past the deadline, but I found an extra moment to work on my SD card interface today and I have it working!

I switched the clock output to the SD card from SH_CLK to /SH_CLK to move the rising edge of the clock to a point where the output from the shift register is stable, and now it works nicely.

It's always a one character Fix!

It’s always a one character Fix!

Continue reading

Retrochallenge 2016/10 – Tools

During Retro Challenge I needed a way to run machine code on my rc2014, as BASIC was incapable of the performance needed to initialise the SD card in bitbang mode.

I didn’t (and still don’t) have an EEPROM burner when I first got my rc2014, and although the version of BASIC in the stock rc2014 ROM does support the USR() function it appears to jump to a hardcoded address within the ROM so this didn’t help me much.

I ended up finding the assembly language source of the BASIC interpreter (or one very similar) and noticed that the address the USR() function jumps to is not looked up directly from the ROM, but copied to a block of information kept in RAM. Once I knew the address of that block I was able to modify it so USR(0) would jump to an arbitrary address.

With this method I was able to poke in arbitrary code and execute it, but this was far from an ideal workflow.

To improve this I wrote some Python scripts which would output the BASIC code to load a binary image into the RC2014′s memory at a given address or run code from a given address. Once appropriate delays were added to avoid overflowing the (1 byte) input buffer on the RC2014′s serial port I was able to combine these scripts with z80asm and a makefile to make a nice toolchain for rapidly deploying and testing programs to the RC2014.

By writing the program such that the RC2014 jumps back to the reset vector at address 0×0000 programs can be developed without the need to constantly reset the RC2014 (unless something goes wrong in the program).

I set up my Makefile with additional commands to output hex dumps of the program, annotated assembly, or to run a program that is already resident in memory.

The only issue I’ve encountered with this system so far is that it is quite slow to load large programs. For my Retro Challenge project the load time was so long that I had to wait for it to finish before reissuing the run command. The automatically sent run program was lost because the loader was still running.

This could be improved by writing a faster loader in assembly which could be bootstrapped with a very small BASIC program. If I had an EEPROM burner a replacement boot ROM could be made which would boot straight into the fast version of the monitor program.

The scripts and Makefile I used are on my GitHub under the RC2014 Tools project. They will work on a Linux system or similar, or on Windows with some modifications.

Retrochallenge 2016/10 – Deadline

I’m at my deadline for RetroChallenge 2016/10 and unfortunately I’m tantalisingly close to having something that works, but not quite there.

I have the bitbang/slow mode working and generating pulses that match the output I get from my Bus Pirate when using it to talk to the SD card. However, the Bus Pirate gets a response and my circuit does not.

I blamed my level shifter for a while. As an experiment I tried writing to the card from the Bus Pirate and reading the response through the level shifter works fine, so that can’t be the problem.

Final State Of Play

Final State Of Play

Bitbang mode was fixed by adding an additional edge trigger circuit. Instead of a synchronous edge trigger I used the simple trick of feeding a signal and an inverted copy of the signal into an AND gate. When the signal goes high the inverted version remains high for the propogation delay of the NOT gate used to invert it, so the output from the AND gate is temporarily high. Since I had a free NAND gate and second free NOT I used these to build an AND. I ended up picking the existing EDGE signal (ie. the synchronous edge trigger) as the input to the new edge trigger. This provided a signal that could be used to make the output flip flop’s latch transparent for only a brief period.

I could probably at this point do away with the synchronous edge trigger and save a mostly unused 74HCT374, but there was no time to test this today. I will test this when I get chance.

With the bitbang mode working I was able to attempt to initialise the SD card at the low clock rate it requires. After some fiddling I discovered that my output pulse train was off by one relative to the clock pulse. In an effort to get things to work I bodged the values I was writing to make the output signal match what I see when using the Bus Pirate. This included adding a new bit to the CONFIG register to drive the serial input on the output shift register. This ensured the Data Out line (MOSI) to the SD card was pulled high, in order to match exactly the Bus Pirate’s behaviour.

CMD0 on Bus Pirate

CMD0 on Bus Pirate

It was difficult to get a screenshot that captured the whole pulse train, but the above shot shows the Bus Pirate sending CMD0 (0×40, 0×00, 0×00, 0×00, 0×00, 0×95) and receiving 0xFF (no response) followed by 0×01 (OK). The shot below shows the commands sent to the Bus Pirate and the response.

Bus Pirate Commands

Bus Pirate Commands

The next shot shows my circuit sending the same output, but recieving no response.

In both cases a large number of clock pulses were sent with the SD card’s chip select deasserted, as is apparently required to initialise the card.

CMD0 From My Circuit

CMD0 From My Circuit

My suspicion is that either my timing is too fast – I’m currently running at 330kHz while the Bus Pirate is running at 33kHz – or the rising edge of my clock is very subtly off with respect to the data.

There are still hardware bugs (the off by one issue, mainly), but the final schematic and final netlist are included below for posterity.

Final Schematic

Final Schematic

Final Netlist

Final Netlist

I plan to continue working on this project after RetroChallenge and will and post further updates as I figure it out.

I also plan to write a post about the toolchain I have setup for running assembly programs quickly and painlessly on the RC2014. Hopefully I’ll be able to post that tomorrow.

Retrochallenge 2016/10 – State of Play

As it stands my RetroChallenge entry is close to working, but not quite there.

The fast mode appears to work and I was able to decode the SPI packets sent to the SD card with OpenLogicSniffer’s SPI analyser module.

Decoded Messages

Decoded Messages

The picture above shows the signals and the decoded data for the SD card CMD0 (Software Reset) message which is the first step in initialising the card. The message is the 6 byte string 0×40 0×00 0×00 0×00 0×00 0×95 where 0×40 is the command (bit 6 is always set), the four 0x00s are the empty parameter section, and 0×95 is the checksum for this command. More information on the SD card SPI protocol is available on this page, which I’ve been referring to regularly for this project.

The eagle eyed will notice that this capture shows an 8mHz clock and therefore the device is running in fast mode. For the SD to initialise correctly it needs to be initially clocked slowly (100-400kHz).

Unfortunately, the slow mode, which I was expecting to be the easy bit is currently not working due to a hack I used to get fast mode working.

Current Schematic

Current Schematic

The current schematic, seen above, shows that the ‘Shift /Load’ input of the output data shift register (U3 pin 1) is driven by the SHIFTING net. This gave the correct timings to load the register when data was written, as the register’s input latch would be transparent while SHIFTING was low. SHIFTING goes high while the autoshift register (U7) is outputting a 1, so the last value seen by U3 is latched in just before the train of clock pulses is generated.

This breaks slow mode because SHIFTING is always low when /BITBANG is asserted, so the output from U3 is always a copy of whatever is on bit 7 of the data bus.

This should be fixable if I can find a better way to load this register before time runs out.

Retrochallenge 2016/10 – Breadboard Fun

Having finally found time to start breadboarding my SD card interface I first made sure that the edge trigger circuit I had tested in ModelSim would work when built with real components.

An issue I had encountered previously when breadboarding RC2014 peripherals was that if I wanted to disconnect the circuit from the RC2014 I would lose track of which wire was which. To work around this this time I took an unused RC2014 protoboard module and soldered on just the usual 90 pin header and a socket header below it. The protoboard can still be used later (minus one row of holes) and now provides something that wires can be plugged into that can be removed from the RC2014.

RC2014 Protoboard

RC2014 Protoboard

Continue reading

Retrochallenge 2016/10 – Due diligence

To avoid the work done designing my SD interface being wasted I decided to verify the concept before going any further.

I used my Bus Pirate to verify that the SD card I have would respond to the commands I expected using the protocol I expected.

The Bus Pirate supports many bus protocols including the SPI bus that the SD card supports in the mode I’m using.

I don’t have an SD card breakout board so I ended up buying a micro SD card with a standard SD adapter and soldering some right angle pin headers to the pads. This gave me an SD adapter that would plug into a breadboard.

Makeshift SD Adapter

Makeshift SD Adapter

Continue reading

Retrochallenge 2016/10 – Building retro computers with modern tools

I’ve been struggling for free time this month for poking around with breadboards and other fun things. To work around this, and still (hopefully) get my RetroChallenge entry done, I decided to use a simulator so I could work on it with my laptop whenever and wherever there was time.

LogiSim Edge Detector

LogiSim Edge Detector

For an earlier RC2014 project I used LogiSim which is simple and easy to use, but I quickly hit some limitations. The built in sequential building blocks (shift registers, latches, etc) appear to support only a limited set of variants. There is no option for asynchronous resets, or transparent latches on the shift registers. It includes combinatorial building blocks (logic gates, etc) also, but these do not appear to work correctly for building sequential circuits, as feedback is not always handled correctly. Because of this I was not able to simulate the exact characteristics for most of the 74 series ICs I was using.

To solve this problem I switched to using Altera Quartus to build a model of the circuit and ModelSim Altera Edition to simulate it. I mainly chose this because I’ve used it previously for FPGA projects, and because if some functionality is missing I can implement it in Verilog.

Autoshift Circuit

Autoshift Circuit

When redesigning the autoshifter circuit (to shift out 8 bits of data after each IO write) I built it as a Block Diagram/Schematic File (.bdf) in Quartus. This allows the design to be entered as a schematic with various logic symbols supported by default. Additional components can be created with a hardware definition language such as Verilog, or by using Quartus’ “MegaWizard Plug In Manager” to configure and insert a variant of an IP core. I set my project up for the Cyclone II FPGA as I have used it for previous projects. To simulate the 74HCT165 shift register I configured a variant of the LPM_SHIFTREG IP core with 8 bits of data, parallel inputs and serial inputs, serial output, and a clock enable pin.

Unfortunately this still does not quite match the 74HCT165 exactly as it has D flip flops rather than transparent latches. I could build my own shift register in Verilog, but to save time I opted to stick with the LPM_SHIFTREG version and ensure that the timings seen in simulation were such that the transparent latches wouldn’t cause a problem.

Simulation

Simulation

In order to test the design I set Quartus up to launch ModelSim and run Gate Level Simulation after compilation. ModelSim can be driven manually through the GUI, but this is fairly fiddly and repetitive. Fortunately it supports scripting via ‘do files’ which contain lists of commands for ModelSim to interpret.

I set up four do files:

  • init.do – Reset, add graphs for appropriate signals, set default values for inputs
  • shift8.do – Drive the data bus to the appropriate values to set SHIFT8 and deassert /BITBANG, then assert and deassert /CONFIGWR
  • write.do – Simulate a write to the device by driving the data bus and /DATAWR signals, zoom graph to fit
  • sdtest.do – Run the previous three do files in sequence, zoom graph to fit

This allowed a fairly quick turnaround by hitting compile in Quartus, selecting the project once ModelSim launches, then typing ‘do sdtest.do’ to run the simulation.

For a different project I could have sped things up by keeping everything inside ModelSim, but this would have required me to design the circuit in a hardware definition language. Since my final target is a circuit built from discrete components and not an FPGA bitstream I decided to take advantage of the Block Diagram/Schematic feature in Quartus. This way everything could be easily translated back to a physical circuit once it was verified as working.

Now I have the autoshift circuit working, theoretically, I just need to find some time to build and test the physical version!

Retrochallenge 2016/10 – Previous version and problems

In my previous post I promised to show the previous implementation of my Z80 SD interface, and to run through the problems which I intend to fix this month.

Original Z80 SD Interface Schematic

Original Z80 SD Interface Schematic (Click to Zoom)

The 74138 (U1) in the top left of the schematic is used to detect and decode IO reads and writes from the Z80. Three bits of the address bus (A7, A1, A0) are decoded along with the /RD line, M1 line and /IORQ line. With this configuration the device responds to any IO address between 0×80 and 0xff. Some more gates will be used to further decode the address later. The lower two bits (ie. the address modulo 4) select a register within the device. Address 0 selects the DATA shift register (U4) for reads or writes while address 1 selects the CONFIG register (U3) for writes only.

One NAND gate from the 7400 (U2A) quad NAND is used to invert the CONFIGWR signal, as the 74138 outputs are active low while the latch input on the 74374 is active high.

In the middle row of the schematic are the 74374 register (U3) that holds configuration information and the 74299 shift register (U4) that is used to transfer data to the SD card. To the right of these is a 74165 (U7) shift register that implements the automatic shifting mechanism for high speed mode along with some more NAND logic (U2B, U2C, U2D) to generate the appropriate signals depending on the operating mode.

The automatic shifting behaviour is implemented by latching the state of the SHIFT8 bit of the config register into all 8 bits of U7′s input register when /DATAWR is asserted (ie. the data register is written to). This fills the register with 1s. The serial in (Ds) pin of the register is connected to ground so with each clock pulse the train of 1s is shifted and the gap is filled with a 0. The serial output of the register (SHIFTING) is NANDed with the clock by U2B. The output from U2B is either a train of 8 inverted clock pulses or a constant logic 1 level, depending on the state of SHIFT8 at the time the DATA register was written to. NAND gate U2C will either invert this train of clock pulses if /BITBANG is high, or reflect the inverted state of the /BITBANG config bit if U2A is outputting a constant logic 1 at the time. Put together this allows either the SHIFT8 config bit or the /BITBANG config bit to control the clock depending on the desired operating mode (relying on the driver to avoid trying to do both simultaneously).

The final NAND gate of the 7400 (U2D) is used to invert the /DATAWR signal to drive U4′s S1 input to select the Parallel Load operation when /DATAWR is asserted or to Shift Left otherwise. S0 of U4 is tied to ground as the Shift Right and Hold operations are never used.

Finally, a 74107 dual JK flip flop was used to divide the RC2014′s clock signal (CLK) by four to produce (Q_CLK). This was initially intended to solve a timing issue, but has caused more trouble than it was worth.

The timing diagram below shows the behaviour of the device when the SHIFT8 bit is set and a write is issued to the DATA address.

Original SD Interface Timings

Original SD Interface Timings (Click to Zoom)

A couple of issues are noticeable:

  • SH_CLK is producing one partial pulse, followed by a gap, followed by 7 real clock pulses.
  • /DATAWR (and therefore SH_LOAD) is asserted for several clock pulses.
  • CLK (actually Q_CLK) behaves strangely.

Most of these issues were introduced by attempts to work around other problems.

Before the clock divider was introduced U7 was emitting a train of 11 clock pulses rather than the expected 8. This is because the 74165 has a transparent latch rather than an edge triggered latch. The Z80 asserts /IORQ for many clock cycles so the train of 1s from SHIFT8 was being reloaded, wiping out the 0 introduced through the Ds input, until /IORQ was deasserted. Introducing and resetting the clock divider was an attempt to prevent the shift registers from being clocked during this period by holding it in the reset state when /DATAWR is asserted.

Unfortunately because the Z80 instructions take a variable number of clock cycles to complete and aren’t necessarily a multiple of 4 cycles the state of the divided clock when /DATAWR is asserted is not predictable. This is likely the cause of the glitchy short pulse seen on CLK as /DATAWR is asserted.

Without this unexpected pulse U4 would not be loaded, as 74299′s the Parallel Load operation is synchronous with the clock, and shares a clock with the Shift operation. Extra logic would be required to create a seperate clock that is a superset of the shift clock.

Given these problems I’m going back to the drawing board slightly. I may try adding the extra logic to clock only the 74299 but if that fails I’m replacing the 74299 with a pair of shift registers – a 74165 for data moving from the Z80 to the SD card and a 74595 for data moving from the SD card to the Z80. This is probably wise anyway as the 74299 is a rare part which is many times the cost of a 74165 or 74595 and supplies are less plentiful.

I’ll also be removing the 74107 clock divider circuit and replacing it with a simple edge trigger circuit to limit the /DATAWR pulse to a single clock.

Hopefully I will have a write up of this new version soon.

Retrochallenge 2016/10

I decided to join in with Retrochallenge 2016/10 this October. I’m also hoping this will provide some incentive to write more posts and updates about other projects once I’m back into the swing of things!

RC2014 Z80 computer

RC2014 Z80 computer

My goal for this Retrochallenge is to finish an SD card interface I started designing for Spencer Owen’s RC2014 Z80 based computer (which was spawned by a previous Retrochallenge, hence the name). This should work with most Z80 computers that don’t do anything crazy to the I/O interface, so I may also get it working on a ZX Spectrum if there is time.

Continue reading

SpeedTwin Update

Recently I’ve been focussed on finishing off my radio controlled model SpeedTwin ST-2. This guy is not the biggest model I’ve built in terms of wingspan, but it wins in terms of chunkiness and complexity. I started it in 2012, but it stalled at some point because everything was blocked by scary “one shot or it’s ruined” style tasks. I recently dug it out and decided to get these things over with so I could get it back on track.

This thing is pretty huge!

Continue reading