OnSpec 90c26

From www.evillabs.net
Jump to navigation Jump to search

Introduction

The OnSpec 90c26 was used on Adara and Microtek flatbed scanners in the late 1990s as a parallel port to SCSI adapter.

IBM-style Parallel Port Information

Port Registers

Port            R/W IOAddr      Bits    Function
----------          ------      -----   ----------------
Data Out        W   Base+0      D0-D7   8 LS TTL outputs
Status In       R   Base+1      S3-S7   5 LS TTL inputs
Control Out     W   Base+2      C0-C3   4 TTL Open Collector outputs
    "           "     "         C4      internal, IRQ enable
    "           "     "         C5      internal, Tristate data [PS/2]

Data Feedback   R   Base+0      D0-D7   matches Data Out
Control Feedbk  R   Base+2      C0-C3   matches Control Out
    "           "     "         C4      internal, IRQ enable readback

The Feedback registers are for diagnostic purposes (except in bidirectional ports, where Data Feedback is used for data input; and the IRQ enable C4).

Pin signals and register bits

<= in   DB25    Cent    Name of         Reg
=> out  pin     pin     Signal          Bit     Function Notes
------  ----    ----    --------        ---     -----------------------------
=>       1       1      -Strobe         C0-     Set Low pulse >0.5 us to send
=>       2       2      Data 0          D0      Set to least significant data
=>       3       3      Data 1          D1      ...
=>       4       4      Data 2          D2      ...
=>       5       5      Data 3          D3      ...
=>       6       6      Data 4          D4      ...
=>       7       7      Data 5          D5      ...
=>       8       8      Data 6          D6      ...
=>       9       9      Data 7          D7      Set to most significant data
<=      10      10      -Ack            S6+ IRQ Low Pulse ~ 5 uS, after accept
<=      11      11      +Busy           S7-     High for Busy/Offline/Error
<=      12      12      +PaperEnd       S5+     High for out of paper
<=      13      13      +SelectIn       S4+     High for printer selected
=>      14      14      -AutoFd         C1-     Set Low to autofeed one line
<=      15      32      -Error          S3+     Low for Error/Offline/PaperEnd
=>      16      31      -Init           C2+     Set Low pulse > 50uS to init
=>      17      36      -Select         C3-     Set Low to select printer
==      18-25   19-30,  Ground
               33,17,16

Note: Some cables, ports, or connectors may not connect all grounds. Centronics pins 19-30 and 33 are "twisted pair return" grounds, while 17 is "chassis ground" and 16 is "logic ground".

"<= In" and "=> Out" are defined from the viewpoint of the PC, not the printer. The IRQ line (-Ack/S6+) is positive edge triggered, but only enabled if C4 is 1.

Here's the same data grouped for ease of reference by Control Out and Status In registers and pins. (Data Out is straightforward in previous table).

<= in   DB25    Cent    Name of         Reg
=> out  pin     pin     Signal          Bit     Function Notes
------  ----    ----    --------        ---     ------------------------------
=>      17      36      -Select         C3-     Set Low to select printer
=>      16      31      -Init           C2+     Set Low pulse > 50uS to init
=>      14      14      -AutoFd         C1-     Set Low to autofeed one line
=>       1       1      -Strobe         C0-     Set Low pulse > 0.5 us to send

<=      11      11      +Busy           S7-     High for Busy/Offline/Error
<=      10      10      -Ack            S6+ IRQ Low Pulse ~ 5 uS, after accept
<=      12      12      +PaperEnd       S5+     High for out of paper
<=      13      13      +SelectIn       S4+     High for printer selected
<=      15      32      -Error          S3+     Low for Error/Offline/PaperEnd


Physical Layer Protocol

PS/2 and Nibble Modes

Sending a Command

D0-D7 <= Command Byte
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x0D (lower #STROBE, #INIT, and #SELECT)
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x0D (lower #STROBE, #INIT, and #SELECT)
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x04 (lower #INIT)

Sending a Value

D0-D7 <= Value Byte
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x07 (lower #STROBE, #INIT, and #AUTOFD)
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x04 (lower #INIT)

Read a Register (Nibble Mode)

D0-D7 <= Command Byte
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x0D (lower #STROBE, #INIT, and #SELECT)
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x0D (lower #STROBE, #INIT, and #SELECT)
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x04 (lower #INIT)
C0-C3 <= 0x06 (lower #AUTOFD and #INIT)
S3-S7 >= Status Byte 1
C0-C3 <= 0x04 (lower #INIT)
C0-C3 <= 0x06 (lower #AUTOFD and #INIT)
S3-S7 >= Status Byte 2
C0-C3 <= 0x04 (lower #INIT)

Read Value = (Status Byte 1 >> 4) & 0xf) | (Status Byte 2 & 0xf0)

Read a Register (PS/2 Mode)

D0-D7 <= Command Byte
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x0D (lower #STROBE, #INIT, and #SELECT)
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x0D (lower #STROBE, #INIT, and #SELECT)
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x04 (lower #INIT)
C0-C3, Tristate Enable <= 0x26 (tristate data, #AUTOFD, and #INIT)
D0-D7 >= Read Value
C0-C3 <= 0x04 (lower #INIT)

Writing Register

D0-D7 <= Register Byte
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x0D (lower #STROBE, #INIT, and #SELECT)
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x0D (lower #STROBE, #INIT, and #SELECT)
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x04 (lower #INIT)
D0-D7 <= Value Byte
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x07 (lower #STROBE, #INIT, and #AUTOFD)
C0-C3 <= 0x05 (lower #STROBE and #INIT)
C0-C3 <= 0x04 (lower #INIT)

Writing a Block

C0-C3 <= 0x05 (lower #STROBE and #INIT)
D0-D7 <= Byte 0
C0-C3 <= 0x07 (lower #STROBE, #AUTOFD, and #INIT)
D0-D7 <= Byte 1
C0-C3 <= 0x05 (lower #STROBE and #INIT)
...
D0-D7 <= Byte N is even
C0-C3 <= 0x07 (lower #STROBE, #AUTOFD, and #INIT)
D0-D7 <= Byte N is odd
C0-C3 <= 0x05 (lower #STROBE and #INIT)

Reading a Block (Nibble)

C0-C3 <= 0x04 (lower #INIT)
C0-C3 <= 0x06 (lower #AUTOFD and #INIT)
S3-S7 >= Status Byte 0
C0-C3 <= 0x04 (lower #INIT)
C0-C3 <= 0x06 (lower #AUTOFD and #INIT)
S3-S7 >= Status Byte 1
C0-C3 <= 0x04 (lower #INIT)
Read Value = (Status Byte 1 >> 4) & 0xf) &pipe; (Status Byte 2 & 0xf0)
...

Reading a Block (PS/2)

C0-C3 <= 0x24 (Tristate, lower #INIT)
D0-D7 >= Read Byte 0
C0-C3 <= 0x26 (tristate, lower #INIT and #AUTOFD)
D0-D7 >= Read Byte 1
...
C0-C3 <= 0x24 (tristate, lower #INIT)
D0-D7 >= Read Byte N even
C0-C3 <= 0x26 (tristate, lower #INIT and #AUTOFD)
D0-D7 >= Read Byte N odd


EPP Modes

Sending a Command

ADDR <= Command Byte

Sending a Value

DATA <= Value Byte


Writing a Register

ADDR <= Register Byte
C0-C3 <= 0x05 (lower #STROBE and #RESET)
DATA <= Value Byte
C0-C3 <= 0x04 (lower #RESET)

Reading a Register

ADDR <= Register Byte
C0-C3, Tristate Enable <= 0x24 (tristate data, lower #INIT)
DATA >= Read Value
C0-C3 <= 0x04 (lower #INIT)

Writing a Block

...
C0-C3 <= 0x05 (lower #STROBE and #INIT)
DATA <= Data Byte 0
DATA <= Data Byte 1
DATA <= Data Byte N

Reading a Block

...
C0-C3 Tristate <= 0x24 (Tristate, lower #INIT)
DATA => Data Byte 0
DATA => Data Byte 1
DATA => Data Byte N


Link Connection

Connect Link

DATA <= 0xFE
DATA <= 0xAA
DATA <= 0x55
DATA <= 0x00
DATA <= 0xFF
DATA <= 0x87
DATA <= 0x78
DATA <= 0x20
C0-C3 <= 0x05 (lower #INIT and #STROBE)
C0-C3 <= 0x04 (lower #INIT)
DATA <= 0xFF
Nibble_Command(2)
Nibble_Value(0)
Nibble_Command(2)
NIbble_Value(IsNibbleMode ? 0 : 1)
Write_Register(2, IsNibbleMode ? 0 : 1)

Disconnect Link

Write_Register(3, 0)
Write_Register(7, 0x48)
Command(4)
DATA <= 0xFE
DATA <= 0xAA
DATA <= 0x55
DATA <= 0x00
DATA <= 0xFF
DATA <= 0x87
DATA <= 0x78
DATA <= 0x30
C0-C3 <= 0x05 (lower #INIT and #STROBE)
C0-C3 <= 0x04 (lower #INIT)
DATA <= 0xFF

OnSpec 90c26 Registers

Link Layer Protocol

Register Type Comments 0x00 R/W B0-B6: SCSI Target
B7: Initiator Mode
0x01 R/W B0: SCSI Connected/Busy (R/O)


B1: SCSI Enable
B4: SCSI Bus State REQ (R/O)
B5: SCSI Bus State MSG (R/O)
B6: SCSI Bus State CD (R/O)
B7: SCSI Bus State IO (R/O)

0x02 R/W B0: Bi-Direction Mode Enable


B5: Read SCSI Bus status into Register 0x01
B7: SCSI Mode Enable

0x03 W
0x04 R ASIC Version
0x07 W B3: Unknown
B6: Unknown