Alexios' Home Page

The Oric IDE Interface 

HomeHardware hacks ► The Oric IDE Interface ►

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.5 of the document.

IDE Devices on Oric Machines

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
D0-D7 From/To host Data bus, lower 8 bits.
D8-D15 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.
ADDR0-ADDR2 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
11XXIDE bus not selected.
XX11IDE bus not selected.
1011IDE bus not selected.
00XXCan't happen on an Intel bus; should be avoided.
1010Host writing to register set #3.
1001Host writing to register set #1
0110Host reading from register set #3.
0101Host 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: 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 ADDR0-ADDR2 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
A3A4A5A6A7-I/O-CS1FX-CS3FX-MSBI/O CTRL Comments
1XXXXX1111Not selected.
XXXX0X1111Not selected.
XXXXX11111Not selected.
00XX101111Not selected.
0100101111Not selected.
0101101100MSB register.
0110100110Register set #1.
0111101010Register set #3.

The I/O memory mapping is as follows:

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:

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
1X1/01/0XXInputInputIsolation.
1X/XXXPort A to Reg A.
1XX/XXPort B to Reg B.
01XX0XInputOutputA to B (Real Time).
01/X0XPort A to Reg A.
011/0X1XReg A to Port B.
01XX1XPort A to Reg A and Port B.
00XXX0OutputInputB to A (Real Time).
00X/X0Port B to Reg B.
00X1/0X1Reg B to Port A.
00XXX1Port B to Reg B and Port A.

The control inputs do the following tasks:

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:

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:

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:

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 following truth table shows what happens depending on the states of the three lines.


R/-W -REG -MSB Action
000Can't happen.
001Write to LSB.
010Write to MSB.
011Interface not addressed.
100Can't happen.
101Read LSB.
110Read MSB.
111Interface 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
000 Never happens.
001 0/110 00110
010 00111 0/110
011 00111 00111
100 Never happens.
101 /0110 /0111
110 00111 00110
111 00111 00111

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:

 

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. :-)

4. References

  1. GNU-Zipped Postscript version of the schematics.
  2. Official ATA (IDE) Specifications.
  3. IDE Devices on 8-bit Machines.