Submitted by alexios on

The Oric IDE Interface was a 1990s attempt to connect Oric micros to IDE disks. The project is obsolete in our days of cheap, gigantic (by 8-bit micro standards) SD cards, dirt-cheap microcontrollers, FPGAs and CPLDs. The whole project could be coded in VHDL or Verilog and implemented on the smallest FPGA chip available without any other integrated circuits on the board. But then, where's the fun in that? And besides, the entire Oric micro in question could probably also be implemented inside a single FPGA chip. (well, here's a fun project for the future)

The Oric IDE Interface is obsolete information. In most ways, it was an experiment and only includes the IDE interface part (which, by the way, doesn't even work properly). To give Oric micros the ability to run IDE disks, a ROM and more electronics would be needed. In essence, something very similar to the circuitry in the Oric Microdrive interface, except with an IDE interface in place of the floppy disk controller (FDC) chip.
This doesn't work! It was my first serious digital electronics project, and I ran across difficulties I wasn't aware of then (most likely a gate glitch), and didn't have the equipment to debug properly (me being a student and all). I have hindsight, equipment and knowledge now. Sadly, I'm no longer a student and I don't have the time.

Before starting, please be aware: this is tentative information! No claims on correctness are provided. The prototyped interface was in fact quite different from the one outlined below, although I couldn't give you the exact details as it's been a good while. In the text below, ‘recently’ et cetera all refer to Spring 1996, when this design was made.

This is version 0.6 of the document.

1 Abstract

This is an initial (and very sketchy) design for an IDE interface for Oric computers.

You'll find loads of errors here. Rely on it. Having said that, I think I ought to warn anyone who reads this: the interface isn't likely to work at all! You could damage your machine if you implement it. And don't come crying to me then! :-)

2 IDE Interface

IDE (also known as ‘AT-bus’) is an interface for connecting advanced peripheral memory devices (hard disk drives, CD-ROM drives, etc.) to IBM ATs and compatibles. The ‘interface’ is actually on the device itself, not on what has come to be called the ‘controller card’. An IDE device already knows how to interface with a Intel 16-bit bus and is very intelligent. Hence, the sole purpose of an IDE ‘interface’ is address decoding and buffering.

In this case, of course, we're not dealing with an Intel bus. Actually, things are even worse, because the workings of the 6502 are quite different than those of Intel CPUs. This requires a bit more ‘glue’ (interface accompanying logic). Even then, though, the interface looks pretty simple: it needs no ROM (though one would be nice), and uses a minimum of cheap, off-the-shelf discrete TTL integrated circuits. You should be able to get all the components easily.

The IDE interface consists of 40 lines, of which some are used by the master device when ‘talking’ to its slave device. Up to two devices can be connected to the IDE bus; one is a master, the other a slave. The host talks to the master device alone. The slave is only accessed by the master. This is completely transparent to the host).

Most of the other lines are used for communicating with the host. Here are the most important connections:

Line Name Direction Purpose
D0D7 From/To host Data bus, lower 8 bits.
D8D15 From/To host Data bus, higher 8 bits. Data on these lines is not always valid (e.g. when transmitting commands, only D0-D7 are used. When data is being moved around, all 16 bits are used).
-IOW From host to IDE The rising edge of this inverted signal latches data from the data bus to the device.
-IOR From host to IDE The falling edge of this inverted signal latches data from the device to the data bus.
-CS1FX, -CS3FX From host to IDE These inverted lines control which set (if any) of the IDE registers is used.
ADDR0ADDR2 From host to IDE These select which register is used in the selected register set.
-RESET From host to IDE This inverted signal cold-resets the drive.
-DASP From IDE to host Used by the slave and master devices for handshaking purposes during reset. At all other times, this inverted signal indicates that either of the IDE devices is working.

Note on register selection:

There two sets of registers: 1 and 3 (the strange numbering comes from their mapping on the PC I/O space at addresses 01Fx and 03Fx), hence the names of the two select lines. The IDE bus is chip-selected when either of the two lines gets asserted. The following table describes how to chip-select the IDE bus in detail:

-IOR -IOW -CS1FX -CS3FX Register Set selected
1 1 X X IDE bus not selected.
X X 1 1 IDE bus not selected.
1 0 1 1 IDE bus not selected.
0 0 X X Can't happen on an Intel bus; should be avoided.
1 0 1 0 Host writing to register set #3.
1 0 0 1 Host writing to register set #1
0 1 1 0 Host reading from register set #3.
0 1 0 1 Host reading from register set #1.

3 The Design

Please see Figure 1 for the full circuit diagram of the interface.

The IDE Interface consists of the following parts:

  1. Address Decoding: decodes 6502 address lines to tell the IDE bus when we're talking to it and what register set we're addressing.
  2. Timing: generates the necessary signals for synchronisation with the 6502 bus.
  3. Data Bus Registers: since this is an asynchronous interface (more or less), we use two bus buffers eto make sure that data is there when we need it. This also includes the control logic for the registers.
  4. Miscellaneous: a couple of simple, easy things like a device activity indicator, etc.

 

Figure 1: Schematic of the Oric IDE Interface.

 

3.1 Address Decoding

This is done by means of the ever so popular 74LS138, an inverting 3:8 multiplexer. This chip has the following purposes:

  • Generates -CS1FX and -CS3FX.
  • Clocks and chip-selects the MSB register (storing the high byte in 16-bit data transfers).
  • Deselects the internal VIA (I don't know if this is required on the Telestrat and if it differs from the way it's done on the Oric-1/Atmos) whenever the IDE interface is accessed.

The 138 is a very handy device, especially in this case. It provides no less than three chip select lines, which allows us to fully decode the lower 8 bits of the Oric address bus. The most significant 8 lines are decoded by the Oric ULA and provided as the negated line -I/O, which gets asserted whenever the host is accessing the hardware I/O page, page 3 (address 03xx). The mux is enabled on the low state of -I/O and A3, and the high state of A7.

Lines A0 to A2 pass through a 74LS173, a quad D flip-flop. The outputs are sent directly to the ADDR0ADDR2 on the IDE bus to select registers.

The I/O CONTROL line is an input to the Oric. It's connected to the CS (not -CS) line of the VIA. A high state enables the VIA; a low state disables it. The address decoder keeps this line at logic 1 at all times, except when the host is addressing the IDE interface. I/O CONTROL then drops to 0 to unmap the VIA (whose registers are otherwise mapped to all of the I/O page).

The following table describes how address decoding is done:

Inputs Outputs Comments
A3 A4 A5 A6 A7 -I/O -CS1FX -CS3FX -MSB I/O CTRL
1 X X X X X 1 1 1 1 Not selected.
X X X X 0 X 1 1 1 1 Not selected.
X X X X X 1 1 1 1 1 Not selected.
0 0 X X 1 0 1 1 1 1 Not selected.
0 1 0 0 1 0 1 1 1 1 Not selected.
0 1 0 1 1 0 1 1 0 0 MSB register.
0 1 1 0 1 0 0 1 1 0 Register set #1.
0 1 1 1 1 0 1 0 1 0 Register set #3.

The I/O memory mapping is as follows:

  • Addresses 0000001111010XXX (03D0–03D7) access the MSB register (eight copies of it, due to partial decoding).
  • Addresses 0000001111100XXX (03E0–03E7) access the registers in set #1.
  • Addresses 0000001111110XXX (03F0–03F7) access the registers in set #3.

For a discussion of the actual IDE registers rather than their mapping on memory, please see the references at the end of this document.

 

3.2 Timing

This might actually be tricky. I base the timing circuit on two observations:

  • Z-80s don't seem to have trouble interfacing with the faster IDE interfaces, so the fact that the device is more powerful than the host is no problem (timing-wise).
  • Going the other way, it's obvious that the IDE device will have no problem talking to a slower host, since the communications is asynchronous.

The only problem with timings is also a problem that has to do with address decoding. Mainly, deciding when to assert -IOR and -IOW. The timing diagram below shows how timing should work (but take this with a pinch of salt):

 

Figure 2: -IOR and -IOW timing.

-IOR latches data from the IDE device to the host at its falling edge. This, in effect, toggles data from the device the moment phi2 goes up. I don't know if this gives enough time for the IDE interface to enable itself. Maybe we shouldn't AND R/-W with phi2...

-IOW latches data from the host to the IDE device at its rising edge. This should be okay ― it more or less matches what the 6502 does, if I'm not mistaken. The equation for this signal is phi2 NAND (NOT R/-W).

 

3.3 Data Bus Registers

We have two of these; one for the lower 8 bits of the IDE data bus, and one for the upper 8 bits. Two 74LS646 bus registers are used for this purpose.

3.3.1 The 74LS646

The 646 is a very useful chip for asynchronous bus applications: it has two 8-bit registers. Depending on the state of the control lines (CPAB, SAB, CPBA, SBA, DIR and -G), the chip can isolate the two buses (known as ports A and B), let data pass through in a specified direction, store data in one of the two registers, and allow one part of the bus to read the other part's register, so we can access data even if we can't have control of the other end of the bus.

The following table describes the operation of the chip depending on the control inputs. States are described as 1, 0, X (don't care), 1/0 (high or low, but no transition allowed), or / (rising edge):

Control Inputs Data I/O Function
-G DIR CPAB CPBA SAB SBA Port A Port B
1 X 1/0 1/0 X X Input Input Isolation.
1 X / X X X Input Input Port A to Reg A.
1 X X / X X Input Input Port B to Reg B.
0 1 X X 0 X Input Output A to B (Real Time).
0 1 / X 0 X Input Output Port A to Reg A.
0 1 1/0 X 1 X Input Output Reg A to Port B.
0 1 X X 1 X Input Output Port A to Reg A and Port B.
0 0 X X X 0 Output Input B to A (Real Time).
0 0 X / X 0 Output Input Port B to Reg B.
0 0 X 1/0 X 1 Output Input Reg B to Port A.
0 0 X X X 1 Output Input Port B to Reg B and Port A.

The control inputs do the following tasks:

  • -G is the output enable signal. A low state enables the chip's selected port (either A or B) to output data. At the high state, the 646 can only input data to its twin registers.
  • DIR is the data flow direction. When DIR is high, data flows from A to B. When DIR is low, the direction is from B to A.
  • CPAB and CPBA are the register clocks. The rising edge of these signals latches data from ports A and B to registers A and B respectively.
  • SAB and SBA are the register output enables. When SAB is high, data from register A is sent to port B (hence the name). When SBA is high, register B is sent to port A.

This makes the chip extremely useful in this case. Unfortunately, we need quite a bit of control logic for all those lines, as described below.

3.3.2 The LSB Register

The LSB register is accessible by addressing either of the two sets of IDE interface registers, as decoded by the address decoding part.

The 74LS646 used for this purpose has its A port attached to the IDE bus. Its B port is the 6502 bus. Hence, DIR is the same as the 6502's R/-W line: when in the high state, direction is from IDE (A) to 6502 (B); when in the low stgate, direction is from 6502 (B) to IDE (A).

The following two cases are taken care of:

  • When reading data from this register, IDE data are copied to the 646's register and output to the 6502 bus. Data are retained in the register in case the 6502 needs the data bus valid for more time than the IDE interface is willing to hold (hence we're using asynchronous communication).
  • When writing to the register, 6502 data are latched to the register and output to the IDE device. Data are retained in the register for the same reasons as before.

3.3.3 The MSB Register

This 74LS646 has its B port connected to the Oric data bus. Its A port is connected to lines D8 to D15 of the IDE bus (wouldn't be the MSB register otherwise!).

The MSB register is addressed in a lot of cases:

  • When the LSB register is read from, data is also clocked to the MSB register from the IDE device. This is done because, when reading from the LSB register, we might need to read 16 bits instead of just 8.
  • When the LSB register is written to, data from the MSB register is also sent to the IDE device. This allows us to send 16 bits to the device.
  • When the MSB register is read from, data is not clocked from the IDE device: this has already been done (when we read the LSB register). Instead, the 646's A register is sent to its B port (the 6502 bus). Asynchronous communication in all its glory, eh?
  • When the MSB register is written to, data from the Oric is clocked into the B register, to be output to the IDE device when next data is written to the LSB register.

3.3.4 Data Bus Register Control Logic

This clearly complicates things quite a lot. Of course, since an IDE device is always 16 bit and the Oric is 8-bit, we can't really escape this. Some drives support full 8-bit operation, but definitely not enough of them (and all of them are brand new EIDE devices ― I wouldn't try to connect a new 1.6 GB hard drive to my Oric just because it supports 8-bit data transfers, all things considered...)

Because of all this, the software will have to be slightly careful of accessing the drive. Accesses to the MSB register do not clock data from/to the device. Only the LSB register can do this. Hence, to work with this scheme, we have to do the following:

  • When writing a word: first store the MS byte onto the MSB register. Nothing is sent to the IDE device by the interface yet. Then store the LS byte onto the LSB register. This now clocks the device. The interface makes both bytes available to it at this time.
  • When reading a word: first read the LSB register to clock the drive. 16 bits of data are copied to the two 646 registers, and the low-order byte is read by the 6502. Then we read the MSB, which contains the high order byte of the previous operation.

Figure 3 depicts the four kinds of accesses needed to interface the Oric to an IDE 16-bit data bus.

 

Figure 3: 8-bit bus to 16-bit bus conversion.

The data bus registers use three signals to tell what to do with themselves:

  • The R/-W signal tells us the direction of data.
  • -REG = --CS1FX AND -CS3FX = CS1FX AND CS3FX. The -REG signal goes to a low state whenever the host is accessing either register set #1 or #3. This is used to tell when the LSB register is accessed, since both register sets are 8 bits wide.
  • -MSB, as output from the address decoding part of the interface, is used to detect accesses to the MSB register.

The following truth table shows what happens depending on the states of the three lines.

R/-W -REG -MSB Action
0 0 0 Can't happen.
0 0 1 Write to LSB.
0 1 0 Write to MSB.
0 1 1 Interface not addressed.
1 0 0 Can't happen.
1 0 1 Read LSB.
1 1 0 Read MSB.
1 1 1 Interface not addressed.

And this table shows the states of the various 74LS646 control lines depending on the values of R/-W, -REG and -MSB. As in previous truth tables, / signifies a rising edge.

Inputs LSB Register MSB Register
R/-W -REG -MSB CPAB CPBA SAB SBA -G CPAB CPBA SAB SBA -G
0 0 0 Never happens.
0 0 1 0 / 1 1 0 0 0 1 1 0
0 1 0 0 0 1 1 1 0 / 1 1 0
0 1 1 0 0 1 1 1 0 0 1 1 1
1 0 0 Never happens.
1 0 1 / 0 1 1 0 / 0 1 1 1
1 1 0 0 0 1 1 1 0 0 1 1 0
1 1 1 0 0 1 1 1 0 0 1 1 1

To ease the implementation of this table into hardware, I use another 74LS138 inverting multiplexer to decode the three input lines. Then it's trivial to tap desired output lines to get the equation we want.

And behold explanations for each case:

  • All four SAB/SBA lines are pulled up. Since this is asynchronous communication, we'll want to make registers available at all times (when the register chips are selected, of course).
  • CPAB/CPBA lines have to be rising edges. Thus, I use a NOR gate for each output line (three of them: CPAB for the MSB register is always equal to CPAB for the LSB register) to provide a rising edge. Phi2 is the other NOR input. Since the 6502 makes available valid data and R/-W before phi2 goes high, the address decoder provides the 74LS138 with its required values, and hence the two 74LS646 registers get a rising edge on their respective clock inputs after addresses and data has stabilised. This is a pretty narrow time constraint: I don't know if it'll work.
  • -G is asserted whenever it's needed. For the LSB register, this value is tapped from the -REG line. For the MSB register, logic is used such that -G is high whenever any of three specific 74LS138 outputs drop to the low state.

 

3.4 Miscellaneous

Easy stuff here. This only consists of an activity LED fed from the -DASP line and a -RESET line which is pulled up so that the drive stops resetting as soon as it gets power. :-)

Tags: 

State: 


Add new comment

Leave a comment