Files
sibo-playground/code/HDK/Psion SIBO Hardware Development Kit 1.0_djvu.txt
T

10693 lines
296 KiB
Plaintext
Raw Normal View History

2026-07-06 18:28:16 +01:00
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
THE PSION SIBO HARDWARE DEVELOPMENT KIT
Version 1.00
May 26 1995
Revision 1.00 Page i
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
(c) Copyright Psion PLC 1990-93
All rights reserved. This manual and the programs referred to herein are copyrighted works of Psion
PLC, London, England. Reproduction in whole or part, including utilisation in machines capable of
reproduction or retrieval, without express written permission of Psion PLC, is prohibited. Reverse
engineering is also prohibited.
The information in this document is subject to change without notice.
Psion and the Psion logo are registered trademarks, and Psion, Psion MC, Psion HC, Psion Series 3,
Psion Series 3a and Psion Workabout are trademarks of Psion PLC.
TopSpeed is a registered trademark of Clarion Software Corporation. Intel 8086 and 80286 are
registered trademarks of Intel Corporation. IBM, IBM XT and IBM AT are registered trademarks of
International Business Machines Corp. Microsoft and MS-DOS are registered trademarks of
Microsoft Corporation. Apple and Macintosh are registered trademarks of Digital Equipment
Corporation. Brief is a registered trademark of Underware Inc. Psion PLC acknowledges that some
other names referred to are registered trademarks.
Revision 1.00 Page ii
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Contents
De IMGrOMUCUON sec ioiciescccetisshicattxstcathaslicatixssdcstenslacatenstecatenslicatinssdesvenslacevinswdvatensldcsvisatibiteislacibedse
2. System Overview..........scccccscssccssssscscsscsseccsscssecssccsesssscssesssscsssesscssesssssesssscssssssscssssssscsessssesesseeees
3. Hardware Overview .........sssccssssssssssscssscssscsssssssesssesssesssesssesssssssssessscssscsssessesssesssnssseesscseoeeees
The Psion SIBO serial protocol ....
Psion ASICs and what they do..
Interrupts .
The current range of Psion periphera
4. The Psion SIBO Serial Protocol .
Hardware Interface ...
The Physical layer .
The Transport layer ..
5. Mechanical Overview ...........sscssscsssssrscsssssessscessecssessessssesseessessscesssessesscssssssscsssessccssesssessosees LD
The Psion Series 3/3a range ...
The Psion Workabout
The Psion HC range
6. ASIC 4.........
ASIC4 Addressing and Modes
Reset and configuration
ASIC4 Pin-out
7. ASIC 5.......scesee
ASICS Mode
Reset and configuration
ASICS Pin-out
8. Example Peripheralls................cccssccssssssssssssseccsscscccssssscsssscccesssscscesssssesssscsssssssssesscsssssscsseeesess OO
The ASIC4 Example Interface Board..
The Psion 3-Link
9. Device Driver Overview...........cccsrsercesssserscersserecssecssesscesssesesssessssessesssesscsscssscsssssssesssessosees OT
Introduction
Device Names and Channel:
Loadable Logical Device Driver Structure
Mandatory LDD Functions ...............
Interrupts and Interrupt Service Routines at
Loadable Physical Device Driver Structure... ccscecesesesseesssesssesesssesesesescseseseenenesesesesesesenenesseesesesusueasaeaeseeessecacaeaeaeenenssesecasaseeeeeneeeeeaeaes
10. ASIC4/ASIC5 Based Device Drivers
Introduction
SIBO Hardware Expansion Channels
Talking to ASIC4..
ASIC4 Registers
Talking to ASICS ..
ASICS Registers...
Communicating with ASIC4
Sending and Receiving data using ASIC4.
Obtaining and using a channel...
Controlling ASICS's UART
Hold and Resumes.
Example Device Driver:
11. An Example Device Driver for ASIC4: A4EXIF.LDD..
Introduction
oo TO eR UU RS gs pad
Mandatory LDD Function:
The Non-Mandatory LDD Functions..........cceee
The handling of synchronous and asynchronous I/O
Interrupts and Interrupt Service Routines
Other important local device driver functions
Structures and Include files «0... cee
12. An Example Device Driver for ASIC5: SYS$AS5.PDD.............ssssssssssssssessessessssesscsessessesseee 77
Introduction
The LDD-PDD interface.
13. Debugging and Testing Device Drivers
Introduction ....
Debugging Techniqu
Further Testing Strategies ae
Memory Lestitng seiscs lech easch oiece siscn Sates losecdestecwcsautsse sean tosevaleslosedtracepudtesiiensdertoanioenteoisebeensse bait es ieettaus adanus teats a a tanta eae
APPENDIX: Source Code Files..
A4EXIF.ASM oo
SYS$AS5.ASM .... 102
Assembler Macros. 1S
Revision 1.00
Page iii
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
1. INTRODUCTION
This document is intended to provide guidance to anyone wishing to construct peripherals for the
Psion SIBO (sixteen bit organiser) range of computers. It describes in detail all aspects of Psion
peripheral hardware development and the structure of the software required to drive such peripherals.
It is the aim of this document to aid third party development engineers in producing production ready
peripherals for any of the following Psion products: Series 3/3a, Workabout, HC and HCDOS.
Mechanical and plastic moulding information and information on how to develop production test
equipment is therefore also included. The emphasis throughout is on the two key Psion peripheral
chips ASIC4 and ASIC5. Detailed information regarding their functionality is provided. The
structure of Psion hardware device drivers is examined both in general outline and then with regard to
two specific examples whose source code is provided in the appendix to this document. It has been
assumed that the reader has some knowledge of a Psion computer such as the Series 3/3a and an
understanding of how such a machine is programmed. A good understanding of electronics, the C
programming language and 8086 assembler is also assumed.
Due to the continuous nature of development, information in this manual may change without notice.
Developers are advised to contact Psion Support to confirm critical details prior to committing
products to manufacture.
Revision 1.00 Page | of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
2. SYSTEM OVERVIEW
All present Psion computers are based around the proprietary SIBO architecture. A SIBO machine is
a battery-powered, 8086-based, computer system. SIBO stands for SIxteen Bit Organiser. The
architecture has been designed with the size, weight and power consumption of computers designed
for the portable environment in mind. The key components of the SIBO architecture are:
e —_ An 8086 class processor .
e A sophisticated power management system that selectively powers subsystems under software
control.
e — Asynchronous, high speed, serial protocol (the Psion SIBO serial interface) for communication
between a machine and its peripherals.
e —_ Solid State Disks (SSDs) that provide fast, low-power, silicon-based mass storage with no
moving parts.
e Hardware protection of the system from aberrant software processes (trapping of out of range
addressing and a watch-dog timer on interrupts being disabled).
Real-time clock.
ROM-resident system software.
Graphics LCD display.
A touch sensitive digitising pad that provides a pointing device (only available on some models).
ISDN-8bit standard combo sound system (only available on some models).
The SIBO architecture has primarily been implemented in custom ICs called ASICs. At the time of
writing there are ten different SIBO ASICs. Some of these ASICs have been designed for use inside
peripherals and these will discussed in detail throughout this document. All SIBO ASICs have been
implemented in surface mount packages and are based on a static CMOS technology. Current SIBO
products in the MC, HC and Series 3 range are based on the same three principal chips. These are
the V30H (an 8086-compatible processor) and two Psion custom chips known as ASIC1 and ASIC2.
Later SIBO products including the Series 3a and Workabout have these three devices integrated into a
single Psion custom chip known as ASIC9. The V30H is an enhanced 16-bit CMOS version of the
8088 found in the original IBM PC. It is software compatible with the 8088. The V30H is a fully
static design which means that all the internal storage elements (i.e. its registers) are made from static
rather than dynamic storage components. This in turn means that there is no minimum clock speed
required to refresh the storage elements and the system clock can be stopped at any time with no loss
of internal state. This technique is used extensively in the SIBO architecture to save power while the
processor is idle (i.e. waiting for an event).
The Psion SIBO serial protocol is a proprietary synchronous two wire serial standard by which host
Psion handhelds communicate with external devices. These devices will typically be Memory Packs
(usually referred to as Solid State Disks or SSDs), RS232 and Centronics printer interfaces, fax
modems, bar-code scanners, and so on. The SIBO architecture provides for two basic forms of
expansion device, namely the extended internal expansion connection (as with SSDs) and the reduced
external expansion connection (the 6-pin S3a serial port or the 11-pin LIF connector). The MC and
HC range of computers have two SSD ports and two separate independent single row 25-way
extended internal expansion ports. These ports have in addition to a Psion SIBO Channel, direct,
parallel I/O from the processor. Direct connection to these machines 7.2 volt battery is included to
support high power peripherals such as Printers and Barcode readers. The Series 3 range of
computers have two ports for SSDs and a single, reduced, 6-pin expansion port, which provides only a
Psion SIBO serial channel and limited power (<25mA). The Psion Workabout has two SSD ports,
two internal expansion points, and one external expansion port. The single external expansion port
uses an | 1-pin Low Insertion Force (LIF) socket which provides a Psion SIBO channel, 25mA of
current and additional lines required for detecting the presence of the Workabout cradle. Each
internal expansion port consists of a single row 26-way connector carrying two high speed serial
ports.
Revision 1.00 Page 2 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
A range of Psion peripherals have been produced for connection to the Psion handhelds outlined
above. These peripherals currently incorporate one of two custom integrated circuits (ASIC4 and
ASICS) that convert SIBO serial protocol signals to data bus TTL level voltages which enable
memory and memory-mapped peripherals to be addressed. ASIC4 is used in SSDs and for memory-
mapped peripherals. A typical ASIC4 peripheral for a Psion S3a would consist of an ASIC4
connected to port C of the host machine and a peripheral chip/device mapped into ASIC4's addressing
space. ASICS is a general purpose I/O chip with a UART on board that can be run in several
different modes. For example ASICS can be used for MCRs (magnetic card readers) or Centronics
interfaces thereby simplifying peripheral design. Psion extended internal expansion ports carries an
active low interrupt input line to the host controller circuitry. The reduced external expansion ports
has an active high interrupt input line. The function of the interrupt can thus be programmed into the
host machine's ASIC1 or ASIC9.
The low-level programming interface to a Psion handheld peripheral is encapsulated within an
appropriate device driver. Psion device drivers are written in 8086 assembler and follow a prescribed
pattern outlined later in this document. The construction of a peripheral and the coding of its
complimentary device driver enable the developer to access its functionality through the means of
library calls in a C program. Examples of such calls are p_loadldd(), p_open() and p_close().
I/O requests are routed through the device driver's strategy vector which maps to the PLIB p_iow ()
call. The device driver is built using the Borland Turbo Assembler and resides in a single code
segment. The device driver can be stored in either RAM or a ROM on board the peripheral or can be
supplied on an SSD (solid state disk).
Revision 1.00 Page 3 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
3. HARDWARE OVERVIEW
The Psion SIBO serial protocol
The Psion SIBO serial protocol is a general purpose method of bi-directional serial data transfer. It
has been designed for synchronous communication between a host controlling device and a number of
slave devices. On a hardware level, the SIBO serial protocol is implemented through Psion ASICs.
The controlling device must contain an ASIC2 (or ASIC9) and the slave devices an ASIC4 or ASICS.
The various Psion ASICs are described in more detail below.
The synchronous SIBO serial protocol interface consists of 2 wires:
CLK ~ - Aclock output from the controller to the slaves. Nominally 3.84 MHz.
DATA - A bi-directional synchronous data line.
The data is transferred using a series of 12 bit frames including 8 data bits each. This equates to a
theoretical maximum data transfer rate of approximately 312 Kbytes/second. Other bits of the frame
contain control information. The "system" is generically defined by 2 protocol layers, namely the
Physical layer and the Transport layer. These layers are described in detail in the next chapter.
Psion ASICs and what they do
ASIC stands for Application Specific Integrated Circuit and as previously indicated, these devices are
widely used within Psion hardware. Summaries of the functionality of each ASIC that is relevant to
peripheral development are presented below:
ASIC1: ASIC1 is the main system controller chip for the SIBO architecture. It connects directly to
the 8086-based processor (i.e. the V30H) controlling all bus cycles to and from the processor. This
configuration effectively forms a micro-controller like device that executes 8086 instruction codes.
ASIC 1 is made up of a number of functional blocks including a bus controller, a programmable
timer, an eight input interrupt controller, an LCD controller and the memory decoding circuitry.
ASIC2: ASIC2 is the peripheral controller chip for the SIBO architecture. It contains the system
clock oscillator and controls switching between the standby and operating states. ASIC2 provides an
interface to the power supply, keyboard, buzzer and SSDs. ASIC 2 includes the eight-channel SIBO
serial protocol controller and provides interface circuitry to both the reduced external and extended
internal peripheral expansion ports.
ASIC4: ASIC4 is a serial protocol slave IC for addressing memory and general memory-mapped
peripherals. It is used in SSDs to convert SIBO serial protocol signals into addresses within the
memory range of the memory pack. ASIC4 was designed to be a cut-down version of ASICS which
was the original SIBO serial protocol slave chip.
ASICS: ASICS is a general purpose I/O chip with a built-in UART that can be set to run in a number
of different modes thereby simplifying the task of peripheral design. For example, it is possible to set
up ASICS to run as a Centronics parallel port interface, an 8-bit parallel I/O port, a serial bar code
controller or a serial RS232 converter.
ASIC9: ASIC9 is a composite chip comprising of a V30H processor, ASIC1, ASIC2 and general I/O
and PSU control logic all on one IC. ASIC9 thus integrates all the digital logic required to produce a
SIBO architecture computer less the memory onto one chip. ASIC9 has a few additional features
such as an extra free-running clock (FRC) and a codec interface for sound.
Revision 1.00 Page 4 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Interrupts
Psion peripherals usually incorporate some circuitry to generate hardware interrupts. Both reduced
external expansion ports (such as the LIF connector on the Workabout or the 6-pin serial port
connector on the S3a) and extended internal expansion ports (such as the two single row 25-way HC
connectors) carry an interrupt line. This is an active high input to the host machine's interrupt
controller circuitry which resides on the logical equivalent of ASIC1. The OS intercepts all interrupts
and can be requested to call a particular function within a controlling device driver. Eight hardware
interrupts are supported by SIBO hardware. IRQO is the highest priority and IRQ7 the lowest. All
interrupts are level triggered and must be serviced in the following order:
e Device asserts the appropriate interrupt request line.
e The interrupt controller unit within either ASIC2 or ASIC9 places onto the data bus the vector of
the highest priority device with an interrupt pending. This enables the CPU to jump to the
correct interrupt service routine code.
e During the interrupt service routine, the software clears the interrupt line by some action specific
to the device.
e The interrupt service routine then informs the interrupt controller that the interrupt has been
cleared by writing to the non-specific end of interrupt (NSEOD) location.
e If another interrupt is pending then go back to the second step.
With 8086-based processors, it is not possible to have nested interrupts.
The current range of Psion peripherals
There are currently a number of Psion peripherals in use and some of the key ones are outlined below
in order to provide the developer with a feel for peripheral design issues:
SSDs: Solid State Disks (or Memory Packs) use a built-in ASIC4 to decode SIBO serial protocol
signals into memory addresses within the memory range of the SSD.
Psion 3-link: The 3-link translates the high speed SIBO serial protocol channel on the S3a 6-pin
reduced external expansion socket into a serial RS232 format. This enables the host machine to
communicate with a PC for example by means of connecting the 3-link unit from the handheld's 6-pin
port to the PC's COM1 or COM2 port. The 3-link contains an ASICS which uses its on-board UART
to convert SIBO serial protocol signals to RS232 format TTL level voltages.
The HC Printer: The HC Printer translates SIBO serial protocol signals transmitted across the single
row 25-way extended internal expansion socket of the host HC into a parallel 8-bit format that is
compatible with the universal Centronics printer interface standard. The HC Printer unit contains an
ASICS running in Centronics interface mode which acts as the serial protocol slave and requires a
small number of support chips.
Psion 3-Fax: The 3-Fax contains an ASIC4 and a memory-mapped modem chip set which permits the
host machine to transmit (but not receive) fax messages.
Barcode: The Psion Barcode reader employs an ASICS running in serial mode to read the data
received from the barcode decoder chip into a SIBO serial protocol format that can be transmitted to
the host ASIC2/ASIC9.
Workabout RS232 Interface: This peripheral connects to the single row 26-way extended internal
expansion port of the Workabout. It incorporates an ASICS running in its default mode to translate
SIBO serial protocol signals into a TTL level (+/-5v) serial RS232 format using ASIC5's on-board
UART. The TTL level RS232 signals are converted into the standard EIA format (+/-12v) before
coming out on the conventional RS232 9-pin D-type connector.
Revision 1.00 Page 5 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
4. THE PSION SIBO SERIAL PROTOCOL
Introduction
The Psion SIBO serial protocol is a proprietary standard for bi-directional serial data transfer between
a controlling device and a number of slave devices. The synchronous interface consists of 2 wires
CLK and DATA as mentioned earlier:
CLK _~ - Aclock output from the controller to the slaves. Nominally 3.84 Mhz for memory
interfaces or 1.536.Mhz continuous for peripherals.
DATA - A bi-directional synchronous data line.
The data is transferred using a series of 12 bit frames including 8 data bits each. This equates to a
theoretical maximum data transfer rate of approximately 312 Kbytes/second. Other bits of the frame
contain control information. The "system" is generically defined by 2 protocol layers:-
e The Physical layer defining the hardware interface and frame structure.
e The Transport layer defines system control and register transfers between the controller and the
slaves.
Using this system, a large number of higher level implementations can be defined. In normal use the
controller will communicate to slaves in a point to point configuration. Multidrop configurations with
a number of slaves attached to one channel of the controller are also supported.
As indicated in the previous chapter, the SIBO serial protocol controller circuitry resides in either an
ASIC2 or an ASIC9 depending on the particular Psion hardware platform. The S3a and Workabout
employ ASIC9 whereas the HC, MC and S3 use ASIC2.
Hardware Interface
As indicated above, the SIBO serial protocol consists of two lines that switch at 5V CMOS voltage
levels:
Clock Line
This line is used to synchronously clock data between the controller and slaves. It is always output
from the controller circuitry that resides in ASIC2/ASIC9. The clock should only be active during the
transfer of data or when the serial channel is continuous clocking mode (used by ASICS). At all other
times it is tri-state pulled low.
Clock Timing Parameters
Parameter
Width of Clock High
Width of Clock Low
Cycle time of clock
Clock Frequency
Data Line
This is a bi-directional line used to transfer data synchronously between the controller and slaves.
The direction of the data line is not determined by the physical layer but by the control information in
the transport layer. This is described in the next section. When no data transfers are in progress the
data line is always set to input on both the controller and slaves. This line is pulled low. Data is
changed on the falling edge of clock by the transmit device and latched into the receiving device on
the rising edge of the clock.
Revision 1.00 Page 6 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
The Physical layer
This section specifies the low level protocol of the SIBO serial protocol. The physical layer protocol
consists of a series of 12 bit frames. There are four types of frames:-
Null frames - Transmitted by controller to synchronise slaves.
Control frames - Control information transmitted by controller to slaves.
Data output frames - Data frame transmitted by controller to slaves.
Data input frames - Data frame received by controller from a slave.
Frame structure
All 12 bit frames have the following structure:-
Bit
Name ST
ST Start bit. This bit goes high to indicate the start of a valid frame.
CTL ~~ Control bit. When low indicates this is a control frame. High indicates a data frame.
Il Idle bit. Used to turn around direction of data line. Normally Low.
DO-D7 Data bits.
12 Idle bit. Used to turn around direction of data line. Normally low.
Null Frame
This is a special frame transmitted by the controller to ensure all slaves are synchronised. It is
generated by transmitting 12 clock pulses with the data line set to input. Since the data line is pulled
low this results in 12 zeroes being transmitted.
Control frame
This frame is transmitted from the controller to one or more slaves. The data line is an output from
the controller throughout the whole frame. The bits in the frame have the following value in a control
frame:
ST Start bit. This bit goes high to indicate the start of a valid frame.
CTL Control bit. Low to indicate this is a control frame.
I1 Idle bit Set low.
DO-D7 Data bits. 8 bits of control information.
I2 Idle bit Set low.
Data Output Frame
This frame is transmitted from the controller to one or more slaves. The data line is an output from
the controller throughout the whole frame. The bits in the frame have the following value in a data
output frame:
ST Start bit. This bit goes high to indicate the start of a valid frame.
CTL Control bit. High to indicate this is a data frame.
Il Idle bit Set low.
DO-D7 Data bits. 8 bits of transmitted data.
12 Idle bit Set low.
Data Input Frame
This frame is received by the controller from a slave. The data line is an output from the controller
for cycles 1 and 2 and input to the controller for cycles 4 to 11. The bits in the frame have the
following value in a data input frame:
ST Start bit. Output from controller. This bit goes high to indicate the start of a valid
frame.
CTL Control bit. Output from controller. High to indicate this is a data frame.
Il Idle bit. Used to turn around direction of data line. Both controller and slave
should tri-state the data line during this bit. This bit should be low due to pull
down resistor on data line. The controller changes the data line from output to
Revision 1.00 Page 7 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
input at the end of cycle 2. The slave changes the data line from input to
output at the start of cycle 4.
DO-D7 Data bits. Output from slave 8 bits of data transmitted by slave. Controller sets data
line to input during these bits.
12 Idle bit. Used to turn around direction of data line. Both controller and slave
should tri-state the data line during this bit. Should be low due to pull down
resistor on data line. The slave changes data line from output to input at the end of
cycle 11.
Data line direction
The following table summarises the direction of the data line.
CONTROLLER SLAVE
Condition CK DATA CK
Outside Frame
Null frame
Control Frame
Data output from controller
Data input to controller:-
Cycles 1-2
Cycle 3
Cycles 4-11
Cycle 12
OO000 0004
Key T Tri-state
I Input
O Output
The Transport layer
This section specifies the transport level protocol that operates above the SIBO serial communication
physical layer. The transport layer protocol controls the serial communication between the SIBO
Protocol Controller (SPC) and a number of SIBO Protocol Slave (SPS) devices. The following rules
apply:-
1) The interface is controlled by the writing of control bytes from the controller to the slaves. Control
bytes cannot be written by the slaves.
Unsolicited data cannot be sent from the slave to the controller.
2) The controlling device contains two registers to communicate to the slaves. These are the control
register (byte, write only) and the Data register (byte or word, read/write).
Control bytes are transmitted to the slaves by writing to the control register.
The format of the control byte is as follows:-
The control word can have 2 distinct formats depending on the setting of bit 7 the Select (S) bit:-
Select = 0 This is the slave select mode. This mode is for selecting, deselecting and resetting slaves.
Select = 1 This is the slave control mode. This mode is for communicating with a slave which has
been previously selected using the select slave command.
Revision 1.00 Page 8 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Slave select mode
The format of the slave select byte is as follows:-
Key:-
R single reset bit.
TU 6 bit ID field.
The 6 bit ID field is a property only of the slave. No slave may have an ID of zero, hence there can be
63 different slaves connected to one controller. The reset bit (R) controls whether the slave(s) are
selected or reset. If R = 0 slave(s) are reset, R = | slave(s) are selected. Slave select control bytes can
be summarised by the following table:-
Description
Reset all slaves
Reset specific slave with ID = xx
Deselect slave (does not reset slave)
Select slave with ID=xx and read slave info (see below).
The Reset function is dependant on the slave. It would normally put the slave into a known passive
reset state.
Select Slave with ID=xx (S=0,R=1)
This is a special command that causes a slave with ID=xx to transmit to the controller an 8 bit
information field. This field depends entirely on the slave but must be non zero. A reply of 0
indicates that there is no slave of the requested ID present.
Slave control mode
This mode is for communicating with a slave which has been previously selected using the select
slave command described above.
The format of the control word in slave select mode is as follows:-
R/W Read/write select. 0 = write, 1 = read
B/W Data transfer size. 0 = 1 byte transfer, 1 = word (2 byte transfer).
S/M Single/Multi transfer mode. 0 = single, 1 = multibyte.
XXXX = 4 bits of data to slave.
Note the meaning of the 4 bits of data (XX XX) is entirely dependent on the slave.
The settings of R/W,B/W,S/M bits in the control word determine the size, type and direction of
subsequent data transfers in the following manner:-
Revision 1.00 Page 9 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
R/W B/W _ S/M
0 0 0 write a single byte to slave
0 0 1 write a number of single bytes to slave
0 1 0 write a byte pair to slave (not implemented)
0 1 1 write a number of byte pairs to slave (not implemented)
1 0 0 read a single byte from slave
1 0 1 read a number of single bytes from slave
1 1 0 read a byte pair from slave (not implemented)
1 1 1 read a number of byte pairs from slave (not implemented)
Write a single byte
This command readies the currently selected slave to receive a byte of data and sets up the controller
so that the next byte (or the LSB of a word) written to its data register will be transmitted to that
slave. Anything further written to the controller's data register will have no effect.
Write a number of single bytes
This command readies the currently selected slave to receive a number of sequential bytes of data.
The slave will expect to receive data bytes until another control byte is received. The controller is set
up so that the next byte (or the LSB of a word) written to its data register will be transmitted to that
slave. All subsequent bytes written to the controller's data register will be transmitted to the slave.
This will continue until another byte is written to the controller's control register.
Write a byte pair
This command readies the currently selected slave to receive two bytes of data and sets up the
controller so that the next word written to its data register will be transmitted to that slave (LSB first).
Anything further written to the controller's data register will have no effect.
Write a number of byte pairs
This command readies the currently selected slave to receive a number of sequential byte pairs of
data. The slave will expect to receive byte pairs until another control byte is received. The controller
is set up so that the next word written to its data register will be transmitted to that slave (LSB first).
All subsequent words written to the controller's data register will be transmitted to the slave. This
will continue until another byte is written to the controller's control register.
Read a single byte
This command triggers a byte to be transmitted from the selected slave to the controller. This byte
can then be read from the LSB of the controller's data register. Further reads of the controller's data
register will return the same data but have no effect on the protocol.
Read a number of single bytes
This command triggers a byte to be transmitted from the selected slave to the controller. This byte
can then be read from the LSB of the data register. This read will trigger the next byte to be
transmitted to the data register of the controller. All subsequent reads of the controller's data register
will trigger further bytes to be transmitted to the controller. This will continue until another byte is
written to the controller's control register.
Read a byte pair
This command triggers a byte pair to be transmitted from the selected slave to the controller. This
word can then be read from the controller's data register. Further reads of the controller's data
register will return the same data but have no effect on the protocol.
Read a number of byte pairs
This command triggers a byte pair to be transmitted from the selected slave to the controller. This
word can then be read from the controller's data register. This read will trigger the next byte pair to
Revision 1.00 Page 10 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
be transmitted to the data register of the controller. All subsequent reads of the controller's data
register will trigger further byte pairs to be transmitted to the controller. This will continue until
another byte is written to the controller's control register.
Timing
The time taken for commands to be processed and data sent is shown below. The time is given in
SIBO pack protocol clock cycles. The length of a clock cycle is nominally 260 nanoseconds for a
clock frequency of 3.84 MHz.
Receive and process the control byte 12 cycles
Byte transfer to or from slave 12 cycles
Byte pair transfer to or from slave 24 cycles
When writing to the controller's data and control registers the following rules apply:-
e After writing to the control register there must be a delay of at least 12 cycles before the data
register is accessed or another control word is written.
e Toread a word from the data register after the command to read byte pair is issued there must a
delay of at least 12 (for control byte)+24 (for the byte pair transfer)= 36 cycles.
e To perform a multiple byte pair write there must be a delay of at least 12 cycles after the
command is written to the control register before the first word can be written to the data register
and a delay of at least 24 cycles between subsequent writes to the data register.
States
A slave can be in one of 5 states. Note a control byte can be received and interpreted at any time.
1) Waiting to receive a data byte or control byte
2) Waiting to receive a data byte pair or control byte
3) Waiting to transmit a data byte or control byte
4) Waiting to transmit a data byte pair or control byte
5) Waiting to receive control byte only
Revision 1.00 Page 11 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
5. MECHANICAL OVERVIEW
This section will contain information regarding mechanical and plastic moulding for Series 3/3a,
Workabout and HC machines that is deemed to be of especial importance to developers who are
considering producing peripherals for these particular Psion platforms.
The Psion Series 3/3a range
S3a/Series 3 Reduced External Expansion Port
The Psion Series 3/S3a personal digital assistants have two SSD slots and provide access to external
peripheral units through a single reduced internal expansion port, port C, on the left edge of the
machine. The reduced external serial interface expansion port from the Series 3/3a forms six wires.
The purpose of each is described in the table below. In addition to data, clock and power an active
high interrupt line is provided. This allows the peripheral device to generate an interrupt within the
host series 3/3a. The level of interrupt that is generated depends on both the machine and the
expansion port that is used. Either ASIC4 or ASICS can act as the other end of the Psion Serial
Interface. With exception of the interrupt line all used signals should be connected directly to the
appropriate pins on ASIC4/5.
ASIC4/5 SDAT
MCLK Serial clock ASIC4/5 SCLK
| 6 | SCK/EXON | Not used in this scenario | Donot Connect____|
Signal Definition
MSD and MCLK form a single master SIBO serial protocol channel. This is normally channel 7 on a
Series 3 and channel 5 on an S3a. The serial channel clock can be continuously enabled to provide a
free running clock for expansion devices. The frequency is fixed at 1.536MHz regardless of the
system clock frequency. SDKs/INT and SCK/EXON are both dual function pins. SDKS and SCK
form a single slave SIBO serial protocol channel. This can be combined with MSD and MCLK to
form a bi-directional high speed data link. SDS/INT can also be used to as an active high interrupt
input. The function of SDS/INT can be programmed in ASIC2 or ASIC9. A rising edge on the
SCK/EXON input will bring the system out of the standby state into the operating state. VCC is a +5
volt supply that is switched off when the system is in the standby state and is switched on when the
system is in the operating or idle state. The maximum current that can be drawn is 25mA. Opening
the pack doors on either an S3a or a Workabout will cut power to external peripherals.
Physical Connector
The reduced expansion port is made up of a 6-way two row connector spaced on a 2x3 way 0.1 inch
pitch. The diagram below shows the physical connector numbering:
Revision 1.00 Page 12 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Looking into Series 3 / 3a
The male plug is connected to a 0.5m long plastic moulded 3-link cable assembly (part no. 25020013)
which is terminated in a six-pin in-line connector which connects to a 6-way 1.5mm pitch transition
header (part no. 47000106).
The Psion Workabout
The Workabout Expansion Interfaces
The Psion Workabout provides a rugged and easy-to-use computer system for a wide range of mobile
corporate needs. The machine can be readily adapted to support various peripheral units such as
barcode scanners and modems attached to the expansion ports. The Workabout has a 26-way
extended internal expansion interface and a special 11-pin reduced external expansion interface.
Workabout Extended Internal Expansion Interface
The pin-out of the Workabout 26-way internal Torson connector is outlined below:
Torson 26 way connector pin Workabout Signal name
NICD (not used)
THM (not used)
VIN (not used)
Revision 1.00 Page 13 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
e = Vccl is 3.0V nominal power supply. Current available from Workabout is limited to 100mA.
e =Vcc2 is 5V nominal power supply. Current available from Workabout is limited to 200mA.
e RUN is low when powered down and high when powered up. It is used to power down or reset
the peripheral module.
e SCK2 and SCK3 are serial data clocks. The clocks are left running continuously at 1.536MHz
when the serial port is in use. They are used to clock the UART in ASICS in the RS232 AT/TTL
and AT/Barcode modules respectively.
e SD2 and SD3 are bi-directional serial data lines used in the RS232 AT/TTL and AT/Barcode
modules respectively.
EINT1 and EINT2 are active low signals for interrupt input.
EXON is an active high signal used to turn on the Workabout.
All of the above logic signals are at 3.0V or 3.3V levels, depending upon the logic supply Vcc1.
Lines currently described as unused relate to a yet unspecified codec interface.
Workabout Reduced External Expansion Interface
For the Workabout reduced external expansion interface, a new | 1-pin Low Insertion Force (LIF)
connector has been designed for connecting the computer to the Cradle System. The computer
mounted male LIF may be weather proofed, the cable mounted female LIF cannot. Currently the LIF
connector cover can be moulded with a polarising pin in one of two positions. The facility exists to
manufacture the cover with the polarising pin in two more positions, giving four possible variants. If
more than four versions are required it is possible to have the cover and the socket bezel moulded in a
range of colours to differentiate between variants. The polarising options are presented below:
Pin numbers
1st (1 GROUND 9
2nd (________] SIGNALS 2,3,4,5,8,10
1,6,7,11
The step arrangement of the LIF Connector pins
Cable mounted LIF (Female plug) Computer mounted LIF (Male socket)
Revision 1.00 Page 14 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
3S 310
@e0000 08
ODOOOO
Cable mounted LIF (Female plug) Computer mounted LIF (Male socket)
Type A and Type B polarisation of the LIF Connector
Revision 1.00 Page 15 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Pin Definition for LIF - PFS Connector
LIF Connector Polarisation Type B
Pin Pin Name Wire Colour Contact Direction Standard Function Cradle usage
No Gauge (Cradle's
perspective)
1 LCA 710.1 Brown third Input Local Computer Active. High when the Used as an enable for the cradle
computer is on. (The Workabout can source resident Xmod 5V supply.
100mA from this pin and the HC/HCDOS
5mA to power remote circuitry)
EXON 710.1 Blue second Output EXternal switch ON, active high (+5V). May be asserted by a cradle resident
Asserted by a remote” device to switch on Xmod.
the computer.
Xmod.
se He 1 a eee eet Battery thermistor terminal. Allows remote“ function
eae of the battery temperature.
meal 1 Bead ie Output Disconnect Local” ASIC, active high (+5V). Asserted by the Cradle ASIC,
(does not apply to Workabout). When this connects the cradle resident Xmod to
signal is asserted the serial channel is the serial channel.
disconnected from the local? ASIC4/5 in the
HC resident Xmod (if present) and instead
connected to a remote ASIC4/5 (if present).
FN Te
| 7 | vin | 28SwG Power supply to computer (+10V)
| 8 | SCLK 710.1 | SerialchannelCLocK.
GND 28 SWG White “fiat Power, [Seval channel Chev —_____ ground and -ve battery Standard function
terminal (1 amp)
SDATA 710.1 Serial channel DATA.
11 STATUS 710.1 Pink third Cai STATUS. Connected to a pull-up resistor to Driven low by an open collector driver
allow connection to an open-collector/drain when LCA is high and the cradle is
driver. Normal usage is: low indicates the powered-up to allow the computer to
presence of a remote” device. sense whether or not the cradle is
connected.
LIF Connector Polarisation Type A
Pin Wire Colour Contact Direction Function
No eine Gauge (Computer's
perspective)
ee oe RS2I2 signal
a a RS232 signal
77 Output | RS232 signal
THERM [7101 [Yellow [ second_[ =] Battery thermistor terminal
[svar [2sswo [Red [tind [- | tvebattery terminal ——SSSSSCSCSCSCSCSCSCSCC~C~*
[3 [pe 701 [Grey [second [Input [ RS232signal OSS
[9 [exp eswo [white [fist [= | Power, signal ground and ve battery terminal —____——SS—~S
Definitions
Computer HC, HCDOS or Workabout
Cradle resident Xmod Expansion module fitted to the cradle, may or may not be present.
HC resident Xmod Expansion module fitted to the HC, which contains the cradle interface and possibly another peripheral.
HC peripheral A peripheral, located in the HC resident Xmod which is connected to the same serial channel as the cradle.
Cradle ASIC An ASICS located on the main cradle PCB which remains connected to the serial channel
irrespective of the state of DLA.
1. | The term "local computer" implies the computer local to the LIF connector, i.e. the HC, HCDOS or Workabout, as opposed to
a "remote" computer which might be connected via a cradle resident Xmod for example.
2. The term "remote" implies something on the other side of the LIF connector to the computer.
3. | The term "local" implies something on the computer side of the LIF connector including devices on an HC resident Xmod.
Revision 1.00 Page 16 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Exploded view of the Psion Workabout
Below is an exploded view of a complete Psion Workabout showing part numbers for various
components and illustrating the positioning of the expansion interfaces.
4
g y
o # ”
4 a § 8
Ss 8
4 gy Fa i
f a Of i
a 8 a a
a «
a 2
8G
Roo
ae
38
a3
3
a @ ¢
me oON Sgt
3
ROS
a 3 g
® S +8
Be $3
$s $8
a 8 28
=
o
j z
a 3
a3 F |
8
a 4 9 Boa ey
3 a a 9 3
a g 4g 1 o
& & a9 3 4 2
# 8 . p 3 3
zh ae 6 ¢ a
3 i 3 f é i 3 "
3 a8 a 8 2 3 §
goa
3 BS
g a 8 Poa
3
5 :
a 8 a 9
a oF a +
& §
ff 42
Oo oN bos
ng
a 3
al
a
«38
i
hoon
2 8 >
f 9° a 38
ag eg
2 as
&
a
$3
Gc @
aa
4
a og
3
4
o §
8
g 8
&
g 3
a
a S$
0 y
8 3
4
8
d
1 a
3 ages
a Be, gy ee!
8 g 3
ae
a
3
8 &
4
9 2 3
p t ° ib
a oO ©
3 Re eS
3 y § 3
4 3
3
ae oe:
n oc = «©
x
»
zg a3
xg
é
a3 28
4 a 3 6
4 4
s 3 ¢ 2 3 os 3
a a 8 §
a 4 hoa gs 4 $
3 ROS *
§ a & aoa
g
g 8 i 3
a 3 5 3
3 i rf
g
Son
8 38
4 og
F 2 9
* 3
8
a a 4
j 4:8
8
a5
3
a
Revision 1.00 Page 17 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
The Psion HC range
HC Extended Internal Expansion Port
The Psion HC range of computers are intended to provide a rugged and powerful mobile computer
system for a wide variety of demanding application requirements. As part of its adaptability, every
element of the hardware is configurable from the plug-in SSDs to the expansion ports for peripheral
devices such as bar code scanners, modems and magnetic card readers. There are two independent
extended internal expansion ports at either end of an HC unit. The top port is termed the "A" port
and the bottom one the "B" port. Each expansion port provides direct I/O with the processor, a SIBO
serial channel, and connection to the power supply. It allows for higher powered expansion devices to
be added by including a direct connection to the main 7.2 volt battery.
Physical Connector
The expansion port is made up of a 25 way single row connector spaced on a 0.1 inch pitch. The 26th
position is a polarising key and should be left blank. The correct mating connector on the expansion
device is made up from a number of Molex C-Grid series 90148 connectors. Pins | and 2 are ground
and should have there own connector placed nearer the board edge to ensure the ground connection is
made first when the expansion device is inserted. The required connectors are Molex 90148-1102 for
the GND contacts and Molex 90148-1123 for the signal contacts. The diagram below shows the
physical position of the connectors.
=$f ene 98148-1182 3
Se : EXPANSION D
=e
sad Abe COMPONENT SID
fet
feu)
HHDE
eorn
AEM
on
38148-1125
raftats afte
+ [o}:o loo) en]
Heonwnm
Zuaorom
Scteorn
aa ne
raftofea
Lsfosfra
wn
Ox
ol
Fr!
wi
Zo
OR
ge
voce
(SPACE?
SIBO COMPUTER
Revision 1.00 Page 18 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Signal definition
The following table defines the 25 way expansion connector:-
Pin No. Name _ Sig. type Comments
GND Power Should mate first when device inserted
GND Power Should mate first when device inserted
ADO BCMOS 8 bit multiplexed address and data bus pulled low with 100 K resistors
ADI BCMOS
AD2 BCMOS
AD3 BCMOS
AD4 BCMOS
ADS BCMOS
AD6 BCMOS
AD7 BCMOS
ALE OCMOS Address latch enable - high when valid address on ADO-AD7
IOWR OCMOS I/O write strobe - active high, data valid on falling edge of IOWR
IORD OCMOS I/O read strobe - high when device can place valid data on ADO-AD7
EES OCMOS External Expansion Select - high during I/O cycles to expansion device
SCLX TCMOS 512 KHz SCL signal for SLD bus - usually Hi-Z and pulled low
DNC N/A For future expansion - do not use.
THERM Resistor Connected to thermistor (bottom slot only - top slot DNC)
VBI Battery Connected to the internal NiCd battery (bottom slot only - top slot DNC)
Vsup Power Unregulated battery voltage - present all the time
INTR ICMOS Active high interrupt input
_EXON ICMOS Active low input pulled up to Vccl - pull low to switch machine on
SD B CMOS SIBO serial protocol data line - pulled low
SCLK TCMOS SIBO serial protocol clock line - Hi-Z in standby needs a pull down
GND Power
Vcc2 Power +5 volt supply, switched off in standby. Max current available = 50 mA
AADNKRWN KH
DNC (Do Not Connect) indicates that the pin should not be connected. The signal types are:-
O CMOS CMOS output to the expansion device.
B CMOS CMOS bi-directional line to the expansion device.
T CMOS CMOS tri-state output to the expansion device.
I CMOS CMOS input from the expansion device.
All the CMOS signals including the ADO-AD7 bus are buffered from the main system busses and so
present a load of one HC series logic gate.
Direct I/O
Expansion devices can be connected to direct processor I/O space using the following signals; ADO-
AD7, ALE, IOWR, IORD, EES and INTR.
ADO-AD7 is the least significant half of the multiplexed address and data bus, this means that up to
128 I/O addresses are available for each expansion device. As only the least significant half of the
bus is available and no bus conversion is done only even addresses can be used.
ALE must be used to latch the address from ADO-AD7 for devices that require a stable address. The
address is valid on the falling edge of ALE. Note that AO will always be low for valid writes to the
expansion device and as such should not be used as an address line, Al should be used as the lowest
order address line. AO can be used as an additional enable signal to stop odd I/O accesses disturbing
the expansion device.
EES is the External Expansion Select and is high during all I/O accesses to the expansion device, i.e.
for I/O reads and writes to address range 100 to 1FF hex. for expansion port 1, and 200 to 2FF for
expansion port 2.
Revision 1.00 Page 19 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
IOWR is an active high signal which is high during all I/O write bus cycles. The data on ADO-AD7
is guaranteed to be stable before the rising edge of IOWR and after the falling edge of IOWR. IORD
is an active high signal which is high during all I/O read bus cycles. The ADO-AD7 bus is
guaranteed to be tri-state before the rising edge of IORD and after the falling edge of IORD. The
expansion device must present valid data on the bus when IORD is high, see the timing details below.
INTR is an active high interrupt input to ASIC1. T his can be used as a directly readable bit or as a
dedicated interrupt input. It must not be driven high when the system is in the standby state as this
input is pulled down and will cause excessive standby current consumption. The diagram below
shows the timing of the I/O write and read cycles.
T/0 WRITE CYCLE
ADS-ADT VALID ADDR
VALID WwW
QOD
FES q_Tadstp _ plyTadhidy,
| Tudstp | Tudhld |
IYO READ CYCLE
ADS-ADT VALID ADDR>
} Tadetp fel adhd ,,
| Thztd Trdste Trdhid
Parameter
Address set up time
Address hold time
Write data set up time
Write cycle pulse width
Write data hold time
Time from Hi-Z to data active
Read cycle pulse width
Read data set up time
Read data hold time
Note the typical values given are for an HC with a system oscillator of 7.68 MHz.
The SIBO serial channel
A single SIBO serial protocol channel is provided on each expansion port. Expansion port | is
connected to serial channel 5, expansion port 2 is connected to serial channel 6. The serial channel
clock can be continuously enabled to provide a free running clock for expansion devices. The
frequency is fixed at 1.536 MHz regardless of the system clock frequency. This frequency is a
multiple of the SLD clock rate and of all normal RS232 baud rates.
High Speed Side Port
Port C on an HC houses an 8-pin in-line connector that allows access to a high speed SIBO serial
interface. This interface is currently used only by the HC cradle peripheral. Its pin-out is outlined in
the table overleaf:
Revision 1.00 Page 20 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
[Pin | Signal | Type | Description,
fo | Sb7_ | InOut__| Bi-directional Serial Data line- Side portC
[8 TSEN Input Battery temperature sensor
Power supplies
Two power supplies are available for expansion devices these are Vcc2 and Vsup. Vcc2 is a +5 volt
supply that is derived from Vsup. Vcc2 is switched off when the system is in the standby state and is
switched on when the operating or idle state is entered. Each expansion device can draw up to 50 mA
from Vcc2. If an expansion device requires more than 50 mA or cannot be powered down when the
system is in the standby state the Vsup power supply must be used. Vsup is the unregulated supply
directly from the main system batteries or from the DC jack input. It will be in the range 5.5 to 12
volts under normal conditions. To use Vsup the expansion device must regulate Vsup to 5 volts with
a low drop-out linear regulator. Care must be taken to not be active and driving any signals high
when the system is in the standby state as Vsup is always present. This can be achieved either in
software or by using Vcc2 as a signal indicating the active state.
Mechanical Information
Mechanical details regarding the numerous build variants and accessories that currently exist for the
HC are presented overleaf. The peripheral expansion boards for these build variants are housed in a
special plastic casing that can be machined to hold the requisite connectors. In the matrix, ae
indicates that the relevant combination of HC and accessory are compatible and an X indicates that
the combination is not compatible. Following the build variant table are two diagrams that display
exploded views of the HC expansion connector and the HC Expansion Board complete with part
numbers and dimensions.
Revision 1.00 Page 21 of 115 pages
The Psion SIBO Hardware Development Kit
Build Variants
With EL Backlighting
Without EL Backlighting
Industrial
Non-Industrial
Keypad Variants
53 Key A/N UK 2401-0026
A/N European 2401-0051
A/N Scandinavian 2401-0050
Numeric only UK 2401-0046
DOS Keypad 2401-0147
53 Key A/N USA 2400-0026
HC Expansion Modules
RS232 / Parallel (Printer) 1502-0001
25 way D type (F) + 9 way Mini DIN
Certified FCC Class B / Passed VDE Class B
RS232 / TTL
1502-0039 (IP64), 1502-0040 (NON IP64)
9 way D type (F) + 9 way D type (M)
Passed FCC Class B / Passed EN55022 Class B
UK Modem (Asic 8) 1502-0010
RJ 11 connector
BABT Approved in UK, BS6301 (Safety)
Barcode Only
HP Wand HBCS-A207 + Plug + EXMOD 1502-0020
Wand Welch Allen + Plug + EXMOD 1502-0021
FCC Class A/ Passed VDE Class B
RS232 / Barcode 1502-0044
9 way D type Quick Loc(F) + 9 way D type (M)
Complies with FCC Class A
MCR / Scanner / RS232 1502-0003
Scanner NipDenso + Plug 1502-0022
Scanner DigVision + Plug 1502-0023
Magnetic Card Reader + Plug 1502-0024
Certified FCC Class B / Passed VDE Class B
LIF / RS232 (Under development)
9 way D type (M) + 9 way LIF- PFS (M)
LIF / TTL (Under development)
9 way D type (F) + 9 way LIF- PFS (M)
LIF / BARCODE 1502-0043
9 way D type Quick Loc(F) + 9 way LIF- PFS (M)
Vehicle / TTL
9 way D type (F) + 9 way LIF- RS232 (M)
16550 RS232 / TTL (Under development)
9 way D type (F) + 9 way D type (M)
Complies with FCC Class A
Printer (High Res.) 1502-0037
Laser Scanner 1503-0012
Fast Charger Variants
Fast Charger with Holster (Due Jan 95)
Fast Charger without Holster (Due Jan 95)
Additional Accessories
Nicad Battery Pack 500 mA 1503-0005
Revision 1.00
Psion PLC (c) May 1995
CHARGER
a a a Ee
i ie IE a a
ee ee
Re ca Da ca
ans he ae Ss eee
FS a a a a
Page 22 of 115 pages
Psion PLC (c) May 1995
The Psion SIBO Hardware Development Kit
Corporate Hand Held (CHH)
Expansion Module Exploded Assembly Drawing
(yovig) Sso0-zoz9
(USENNN LYVd YSLINO OSTY) (A3N9) £000-20z9
YANVIG NOISNVdX4d 138V1
(440 2) 2000-z0¢g
WSO IZOd WWOXZZ% MINIS
(OV1E) 9107-2018
(AJN9) 9101-2018
ONITINOW Y3LNO NOISNVdxX3 OLS HHO
(wov1d) $10Z-Z018
(AIUD) SLOL-ZOL8
ONIGINOW YSNNI NOISNYdX3 HHO |
6000-0072
ANVIG dd
SNOISNSNIG YSLLNS
ANVIG NOISNVdX3 138V1
Page 23 of 115 pages
Revision 1.00
Psion PLC (c) May 1995
t
The Psion SIBO Hardware Development
QrOr o22 ILD :xW4
008! 802 120 “7131
1G) HIM
NOONOT N/OIl
AS 18NOQYVH 61-21
Jd NOd
MSV LENOd Ni dl
JNWOS ION OG
(SOs 2) ONDOEL =O
w300 34 OL G3U0Y vey
26,
94 01 GMQy SFI NOILWOOT
26/1/91
Sa @ SINSNOGNOD 40
wa) 38 OL G200V vw
26/0178
Gadd NOWOWISIS
AHOIBH LN3NOEWOD W207
06 /c0/zal
108 X3T0K
a300¥ $89 8ou93~N09
oss 9792
SSI Sas
SONVHO,
SmAOVd NOISNVdx4
SH T1¥ A044 GssyINGS
NOILYWAOSANI 4H
L SMOHS SONIMVAC Sit
LH513H LN3SNOdWOD
X¥W ONIMOHS 311 408d
216
cay) Y_NOISN3WIC
C30N31LX3
CAVONVLS
JdWwOS aNv
qa.0N3d vaav
A11V901 NO3IaLS34
COMPONENT HEIGHT RESTRICTION
(SEE PLAN VIEW)
(SOd 2) ONIMDVYL ANY
WOS4 3384 38 O1 voav
CAVA 92 WiOL) SYOLO3NNO9
LTO
SOd 2) SIN3NOdWOD ANY
WOSs 3384 34 OL vaav
: @szaze @ S3143S 8y106 X370N
a2
4.5 BOTH SIDES
1
|
31.75 CRS l 31.75 CRS
Page 24 of 115 pages
Revision 1.00
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
6. ASIC 4
What is ASIC 4?
ASIC4 is custom integrated circuit designed for use in Memory Packs (called SSDs) and peripheral
devices. Its primary purpose is to convert the PSION Serial protocol into the signals required to
address memory and memory-mapped peripherals. A typical Series 3/3a ASIC4 peripheral will
consist of an ASIC4 connected to port C of the host machine and a peripheral chip/device mapped
into ASIC4's addressing space. An example could be an ASIC4 connected to a simple 1k memory
device:
Chip select
To write a value, <v>, to address <addr>, the appropriate control codes must be sent along the port
C Psion Serial link to assert <addr> on ASIC4's address outputs and <v> on ASIC4's data outputs.
ASIC4 Addressing and Modes
ASIC4 has an 8 bit data bus and a 28 bit address bus. Also provided are eight chip select lines that
form selectable addressing blocks each of a size defined by software. The default is 32Kbyte/block.
The filing system will set this to the appropriate size while accessing memory in the upper portion of
the address space.
ASIC4 has two basic modes of operation, namely ASIC5 Compatibility (or SSD) mode and ASIC4
Extended mode. To select the mode, ASIC4 must be selected with an appropriate ID. This is
achieved by writing a SIBO serial protocol slave control frame, as detailed in chapter four, to the
ASIC prior to sending any read or write requests. After sending this frame, the so-called Info Byte is
read off the data bus. Details concerning the meaning of the various Info Byte bits are provided in the
following section. In the case of SSD mode, the ID is 2 and for ASIC4 Extended mode, the ID is 6.
Putting ASIC4 into SSD mode makes the chip compatible with all current versions of existing SSD
software in production by Psion including all HC, series 3/3a and MC software. In this mode, ASIC4
mimics an ASICS in pack mode (see next chapter). This is because ASIC4 was originally designed to
be a cut-down version of ASICS and so from the outset it was necessary to make previously existing
ASICS software run on the new chip. The maximum address space in SSD mode is 21 address bits
and 4 chip selects (which comes to 4 x 2Mb). In ASIC4 Extended mode, ASIC4 is capable of
addressing up to 28 address bits (256Mb). In this mode, in addition to the Info Byte, a further 4 bits
of information can be elicited from the state of the address lines A27-A24 during reset. Of these bits,
the state of A27 (bit M) determines whether ASIC4 is going to be used as a standard SSD (M=0) or in
a mixed mode (M=1) comprising of memory devices and peripherals. It is only the latter case which
is of interest to the potential developer since this is the mode intended specifically for peripheral type
expansion. In mixed mode ASIC4's address space is split into two equal halves. The lower half of
the addressing range is set aside for memory-mapped peripherals and can be used for any purpose.
The upper portion of the address space is reserved for pure memory. The Series 3/3a, Workabout and
Revision 1.00 Page 25 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
HC filing system is able to use this memory (which does not have to be present) as an additional
storage medium. Typically it will be a ROM containing the software that controls the peripheral. On
reset, configuration data is supplied to ASIC4 on its data bus lines which the filing system can read
in order to determine what form of and how much memory it has available in this upper region.
In mixed mode chip selects are split into four selectable peripheral blocks and four selectable memory
blocks. CSO-CS3 are for peripheral access. CS4-CS7 select memory devices one to four. This set-up
is illustrated below:
Peripherals
S1
$2
$3
Total
Addressing S4
Range Memory
(256Mb) SS
S6
S7
Reset and configuration
As indicated earlier, in mixed mode, following a reset or power up ASIC4 will read the form in which
to configure itself from the data on data lines DO-D7 (the Info Byte) and address lines A24, A25, A26,
A27 (most significant nibble of the Extended Info Byte). The table below shows the meaning of each
of these lines during reset.
| A27 | A26 | A25 | A24 | D7 | Do | Ds | D4 | D3 | D2 | Di | DO |
Don't care, some 000 RAM 00 1 device No memory
codes are reserved. | 001 Typel Flash | 01 2 32Kbyte
000 No peripheral | 010 Type2 Flash | 10 3 64Kbyte
001 T3Link 110 ROM 114 128Kbyte
010 3Fax 256Kbyte
Contact Psion for 512Kbyte
an official code. 1Mbyte
Pull up, pull down resisters would usually be used to place these lines in the desired state on reset.
High value resisters of typically 100k would be used to allow ASIC4 and bus devices to drive these
lines to other levels during normal operation.
ASIC4 should be powered from its host Series 3/3a/HC. High current peripheral chips or volatile
memories should have their own supply. Whenever the Series 3/3a/HC is powered down, has its
batteries removed, or has it's pack doors open, any attached ASIC4 will be powered down and reset
upon resumption of power. Taking the 3Fax as an example with one Read Only Memory device of
512k the required configuration is:
Revision 1.00 Page 26 of 115 pages
The Psion SIBO Hardware Development Kit
ASIC4 Pin-out
Pin No Pin Name
50 DO
49 D1
48 D2
47 D3
46 D4
45 D5
44 D6
43 D7
13 AO
12 Al
11 A2
8 A3
7 A4
6 AS
5 A6
4 AT
3 A8
2 AQ
1 Al0
64 All
63 Al2
62 Al3
61 Al4
60 Al5
29 Al6
28 Al7
27 Al8
25 Al9
24 A20
23 A21
22 A22
21 A23
20 A24
19 A25
18 A26
17 A27
37 CSO
36 CS1
35 CS2
34 CS3
33 CS4
32 CS5
31 CS6
30 CS7
16 OE
14 WR
15 VPS
39 POR
40 SCLK
38 SDAT
59 SDIR
51 LBO
56 MCSD
52 INO
53 INI
54 IN2
55 X2D2
57 ATST
10 VDD
42 VDD
9 GND
26 GND
41 GND
58 GND
Revision 1.00
Direction
VO
vO
fe)
~*=“O0O000000000
fo)
PWR
PWR
PWR
PWR
PWR
PWR
Pin Description
Databus
Databus
Databus
Databus
Databus
Databus
Databus
Databus
Address bus - register ATO
Address bus - register ATO
Address bus - register ATO
Address bus - register ATO
Address bus - register ATO
Address bus - register ATO
Address bus - register ATO
Address bus - register ATO
Address bus - register AT 1
Address bus - register AT 1
Address bus - register AT 1
Address bus - register AT 1
Address bus - register AT 1
Address bus - register AT 1
Address bus - register AT 1
Address bus - register AT 1
Address bus - register AT2
Address bus - register AT2
Address bus - register AT2
Address bus - register AT2
Address bus - register AT2
Address bus - register AT2
Address bus - register AT2
Address bus - register AT2/Oscillator Output in PSPRAM Mode
Address bus - register AT3 Inputs to set device size on reset
Address bus - register AT3 Inputs to set device size on reset
Address bus - register AT3 Inputs to set device size on reset
Address bus - register AT3 Inputs to set device size on reset
Device chip selects
Device chip selects
Device chip selects
Device chip selects
Device chip selects
Device chip selects
Device chip selects
Device chip selects
Output Enable/Refresh in PSRAM Mode
Write pulse
VPP control
Reset input
Serial clock input
Serial Data input
Protocol Direction indication Bit
Low Battery detect driver output (Open drain)
PSRAM Mode Select
General Purpose inputs
General Purpose inputs
General Purpose inputs/Refresh Disable in PSRAM Mode
Oscillator Input for PSRAM Mode
Test input (pull high to put device into address test mode)
Power inputs
Power inputs
Ground
Ground
Ground
Ground
Psion PLC (c) May 1995
Page 27 of 115 pages
The Psion SIBO Hardware Development Kit
A11 A12 A13 A14 A15 SDIR GND ATST PS OSCIN IN2. IN1 INO LBO DO D1
- LU Li Lt Ly ae L Ls LI Li
62 61 60 57 56 54 53 52 51
64
A10 48 D2
AQ 47 D3
A8 46 D4
A7 45 D5
A6 44 D6
AS 43 D7
A4 42 VDD
AS ASIC4 41} —J GNo
GND 40 SCLK
VDD 39 POR
A2 38 SDAT
Al 37 cso
AO 36 cs1
WR 35 cs2
VPS 34 CS3
OE 33 cs4
17° 18 «#19 20 21 22 23 24 25 26 27 28 29 30 31° 32
Rigizipininigiolgipinipimdeig
A27 A26 A25 A24 A23 A22 A21 A20 A19 GND A18 A17 A16 CS7 CS6 CS5
OSCOUT
Diagram of ASIC4 Pin-out (NEC)
Revision 1.00
Psion PLC (c) May 1995
Page 28 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
7. ASIC 5
What is ASIC 5?
ASICS is custom integrated circuit designed for use in Memory Packs (called SSDs) and peripheral
devices. ASICS provides three primary functions. A built in UART provides for serial
communication at baud rates of up to 48000 baud. General purpose I/O pins provide for a wide range
of control and communication applications. Finally ASIC5 provides address and data lines for access
to memory devices and memory mapped peripherals. A typical ASICS peripheral such as the 3Link
consists of an ASICS connected to port C of a series 3/3a, a ROM memory device mapped into
ASICS's addressing space and line drivers to convert the UART signals from ASICS into standard
RS232 levels.
Chip select
ASIC5 rea Memory
RS232 Line Drivers
Psion Serial link
ASIC5 Modes
ASICS can operate in two modes. In pack mode ASICS generates all the address, data, and control
signals necessary to access memory devices. No peripheral functions are available in this mode. In
peripheral mode ASICS has only limited memory address capabilities as some or all address and
control lines are reused for I/O purposes. ASICS is placed into peripheral mode by setting the
peripheral bit in ASIC5's PBMODE register.
ASIC5 as a UART
ASICS contains a full function UART which supports baud rates of up to 48000 bits per second. In
order to use ASIC5 as a UART, ASICS5 must be placed into peripheral mode. In this mode the input
signals PAO, PAI, PA2, PA3 become the UART inputs RX, CTS, DSR, and DCD respectively. The
output signals PDO, PD1, PD2 become the UART signals TX, RTS, and DTR. Serial data is
transmitted from the TX line. Incoming serial data is received by the RX line. RTS and DTR can be
used for handshaking or as general purpose outputs and need to be set high or low explicitly by
software. CTS, DSR, and DCD can be used for handshaking or as general purpose inputs.
The Psion SIBO serial link which connects ASIC5 to a host computer is a two wire interface
consisting of a data and a clock line. ASICS generates it's baud rate clocks from this clock line.
Under normal operation, clock pulses along a Psion SIBO serial link only accompany data frames. To
be able to generate baud rate clocks ASICS requires a steady clock from the Hosts Psion port. To
facilitate this, Psion serial links can be put into a mode called continuous clocking where clock pulses
are generated regardless of whether there is any actual data to be transferred. Continuous clocking
Revision 1.00 Page 29 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
increases power consumption and Psion serial links should not be left in this mode unnecessarily.
The UART portion of ASICS is capable of generating interrupts when characters are received, when
the transmitter is awaiting a character to send and when there is a change of state on the handshaking
lines. ASICS has only one, active high, interrupt line. This line is shared between these interrupt
sources. When an interrupt is generated it is the responsibility of software to determine the cause of
the interrupt.
A character to be transmitted should be written to the Transmitter Holding Register where ASICS will
convert it to serial form for transmission. The register will be emptied once the character has been
transmitted. ASIC5 contains no internal buffering. The Transmitter Holding Register must be empty
before writing a character to it. The state of the Transmitter Holding Register is reflected in the
Transmitter Empty bit in the UART status register. Enabling the Transmitting Holding Register
interrupt will cause ASICS to generate an interrupt every time that the Transmitting Holding Register
becomes empty. Reading the UART Status Register will clear the interrupt. Received characters are
copied into the Receive Character Register. If the Receive Character Interrupt is enabled, ASICS
generates an interrupt on each character received. If the character is received in error due either
parity, framing or overrun errors, appropriate bits in the UART Status Register are set to reflect this.
ASIC5 for parallel I/O
Lines PAO-PA7 form a general purpose, non latched, 8 bit input/output port. All access to this port
take a total of twelve clock cycles. The clock is generated from the Psion Serial Link. Actual
memory access cycles only last for one clock cycle. Twelve cycles are required because data being
sent or received needs to be converted to or from the Psion serial format. Because of the conversion
read accesses occur on the third cycle, write cycles on the twelfth. This is usually of no real
consequence to the peripheral designer
In peripheral mode CSO will be taken low for one clock period each time Port A is accessed. Data
outputted from this port will remain valid for only the period that CSO is low. In pack mode Port A
forms the data bus in memory mapped systems. A read from or write to Port A in this mode will
result in one of the lines CSO-CS3, being taken low for one clock period. The line which will be
taken low will depend on the address being generated for the access. During read cycles OE line will
be taken low and remain so for 10 cycles. Data present on PAO-PA7 must remain stable for the last
nine cycles. During write cycles the WR_B line will be taken low for the second half of the cycle over
which one of CSO-CS3 is low. If port B is set to counter mode, accessing port A will result in the
counter being incremented upon completion of the access.
ASICS can be programmed to generate an interrupt whenever the state of line PA4 changes. Reading
port A will clear this interrupt. One use of PA4 is as the BUSY line in a Centronics port
implementation.
The Lines PBO-PB7 can be programmed to operate in four different modes. Two of these modes are
for testing purposes and will not be discussed further. In latched mode, data written to the Port B
resister is latched onto the Lines PBO-PB7 and will remain there until a following write to Port B or a
reset condition occurs. In counter mode, the binary value on lines PBO-PB7 is incremented following
any access to port A. With ASICS in pack mode lines PBO-PB7 form the address lines AO-A7.
Placing port B into counter mode allows 256 consecutive memory locations to be read without need to
set-up the address of each access.
Lines PDO-PD7 are general purpose outputs. In pack mode these form the address lines A8-A15. In
peripheral mode lines PDO, PD1, PD2 become UART outputs.
Lines PCO-PC4 in pack mode form the address lines A16-A20. In peripheral mode lines PC4 and
PC7 become inverted inputs and can be used as edge triggered interrupt lines. PC5 becomes the
interrupt output line. PC6 becomes a general purpose latched output. PCO-PC3 become a dual
synchronous serial port for use in magnetic card systems.
Revision 1.00 Page 30 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
ASIC5 for Barcodes
Psion barcode peripherals use the UART functionality of ASICS to receive data from a dedicated
barcode scanner IC.
ASIC5 for Card readers
Magnetic card readers generate clocked serial data. ASIC5 contains two synchronous serial ports for
connection to card readers or other peripherals which generate clocked serial data.
Reset and configuration
Following a reset or power up ASIC5 will read the form in which to configure itself from the data on
data lines PAO-PA7. Line PC6 is used to select whether ASICS is to operate in pack or peripheral
mode. The table below shows the meaning of each of these lines during reset. In peripheral mode
lines PAO-PA7 should be set to give an indication of the type peripheral the ASICS is forming.
combinations of types can be used.
000 RAM 00 1 device No memory
001 Typel Flash | 01 2 32Kbyte
010 Type2 Flash | 10 3 64Kbyte
110 ROM 114 128Kbyte
1 1 1 Write protect 256Kbyte
512Kbyte
1Mbyte
Peripheral Mode Type
RS232 port
Centronics (Parallel) port
Hx KK KK XX
xo KKM KK XX
0
0
0
0
0
0
0
0
Pull up, pull down resisters would usually be used to place these lines in the desired state on reset.
High value resisters of typically 100k would be used to allow ASICS and bus devices to drive these
lines to other levels during normal operation.
ASICS should be powered from its host Series 3/3a, Workabout or HC. High current peripheral chips
or volatile memories should have their own supply. Whenever the Series 3/3a/HC is powered down,
has its batteries removed or has its pack doors open, any attached ASICS will be powered down and
will be reset upon resumption of power.
Revision 1.00 Page 31 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
ASIC5 Pin-out
A10 Ali A1l2 Ai3 NC A14 A15 DO D1 D2
DONO o net
ASIC5
14 15 16 17 18 19 20 21
MAMAMAAMMo
WR VPS OE A20 A19 NC A18 A17 A116 CS3 CS2
ASIC 5 current pin-out (TI version CF30179)
Revision 1.00 Page 32 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
8. EXAMPLE PERIPHERALS
The ASIC4 Example Interface Board
The ASIC4 Example Interface Board detailed in this chapter is intended to provide the developer with
a simple example of a Psion ASIC4 peripheral. To this end, the actual practical usefulness of the
hardware is of secondary importance. In fact, the board essentially consists of eight LEDs connected
via some latches to an ASIC4. Using a device driver, the host machine is able to control the status of
the LEDs. Specifically, the board translates SIBO serial protocol signals into a parallel 8-way data
bus format that can be used to set the various 74HC series latches and gates. It is intended that the
board can be readily adapted to run on all currently available Psion machines. The only physical
change that need be made concerns connection to the host machine's external expansion interface.
In the following circuit, an eight-bit tri-state data buffer, U3, and an eight-bit output data latch, US,
are commoned together to the eight LEDs thereby enabling their status to be sensed and set. In
addition, a facility for generating hardware interrupts is provided by means of a suitably connected
switch, S1, and a third eight-way buffer, U4. U4 is the interrupt switch status buffer. It holds the
values of the two input switches S2 and S3 which are read as part of the interrupt service routine.
Depending on the value of the switch positions, a different response can be output to the LEDs from
the set buffer, US. One of the D-type flip-flops in U6 is used to latch hardware interrupt signals into
the INT line (pin 5) of the reduced external expansion interface connector. On completion of the
interrupt routine code, it is necessary to reset this flip-flop and hence the interrupt hardware by means
of a write to address Al. Address decoding is provided by two 2-to-4 decoders on chip U1 paralleled
to address lines AO and Al. A circuit diagram of the ASIC4 Example Interface Board is presented
overleaf for the case of a host S3a.
Note that it is possible to construct this circuit with or without the compiled driver code in an on-
board ROM. The developer merely has to set the resistors on the three data bus lines DO-D2 such that
the corresponding info byte conveys the appropriate information. The meaning of the various bits in
an ASIC4 info byte was discussed earlier in chapter 6. If a ROM is to be used, then the info byte read
off DO-D7 on reset should include bits 001 on lines D2-D0. This requires the R1/R2 optional resistor
to be connected to Vcc. If a ROM is not used, as was the case with the constructed test circuit, the
data bus lines D2-D0 should be set to 000. This is done by choosing the resistors connected to ground
from the three R1/R2, R3/R4 and R5/R6 pairs.
Revision 1.00 Page 33 of 115 pages
Psion PLC (c) May 1995
The Psion SIBO Hardware Development Kit
VOD
voc voc voc voc
3
cs ca cio _|+ caa For 128K Bute ROM fit option resistors Ri, R4, RG, RE and Rio eibe
idon toon ioon Our evs For no ROM fit option resistors RZ, R4, RE bo 2
ue ve ve as VOD
SNC GND GND GND
1
3
Xf RE-/R4
vor GND
res Di 2g 100K
ag voo | 338
bo = ae base es Do
Di 14 Bd 1
AS Bi
DE Be be (45 De
veo DS ce be Cie mE v Biel
Da 18 ba SNC
oS aé ba Te DS
az BS
R22 [ery AS be 20 [T= 3
100K Br aS BS [ei isk RE RE
aio fa 100K
ort ze | 22 bz z
Al2
ails oe [24
7 ate 1
aaa oe awe hae
Aiz L
ae GND
eto nigga | ao
vor voc
ZEK—ine ROM DS R16 100K
Ss Is
RT-RE RS/RL0
vos z z
7 FaHcT4a
ja oR oR
R26
Rea 100K 1 1 DF R20. 100K
LooR
GND
GND
Ree SND
aoe t R27 ba
voc LED GND
CONNL
sp7 bo * 0
sck7 b-# = Bo 18/ivi = 1ai +329
= Di is a_i LED ND
sDSs/INT iv2 0 1Az
SCKS/“EXON a Wie D2 14 is. 1AS & P2
z z Ds iz = Ps
Wor * a vo ava iaa
4 z bas ii_F4
She , a. be revi 281 Ge re LED GND
YE 2Yz ZAz
CON COMMS CONN be oer te be S| S02 282 (re Pe
bre) S)5: Soy bere
FPS4HC1sg
GND te het LED GND
vor 28 brs
DL uza
1 OE 4 ae FaHceas FaHCETS
z 3 ORD LED ND
2 cso 2 FaHca4d
A t ua
WF Baves clr Se T4Hese DO 18 Tyg LAL
GND 1006F El tel ge: {ee LED GND
1B a De 14
ive 9 1az
Mee Nf 14) 4 vo BS tetiva iad
D2 GND U2B is ba 3
B vi Zvi ZAL
4 WR 4 oS + LED GND
Y2 2vz BAZ
= 6 Lor 15 bss
Gc YS 2yYe 2As
=P = Dre 3/oy4q Baa
FaHCLss
yo OBAYSS FaHese ee 470 LED GND
GND Vos a Si voc ¥ v
vos J" GND SND DATA OUTPUT
vor FaHCe44
DOS la Us6Al Lk Interrupt Sw
a:
= Ne Saal = a B Db 2 CC? 1993 (PSIOS PLS.
aa ADDRESS R-M FUNC 3 Interrupt In
+ Bava fal RYH Read & write to latch SLK Eiki Sp ee) omnes
GND rs Md Clear Interrupt els; = R25
1 R Read status 100K Poe REY : oO
status Bit Func F4HCr4 Title
a Ineut a
L Tneut 1 > ASICS Example IF
2-5 Not Used GND GND Size Pocument Number REV
6 Interrupt Line B 7 lo.s
? Interrupt Latch :
Date: Aerial 19, 1995|[Sheet i_of Z
Page 34 of 115 pages
1.00
1S10n
Rev
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
The Psion 3-Link
The Psion 3-Link is an ASIC5-based peripheral that enables the user to transform SIBO serial
protocol signals into RS232 format data so that a host Psion machine can communicate with a PC or
printer. The diagram below shows the schematic of a TTL level RS232 based expansion device. The
interface is based around ASICS and allows the standard RS232 device driver contained in EPOC to
be used.
Transistor Q1 provides a switched power rail for any other expansion device. This rail will
automatically be switched off when the RS232 port is closed. D1 is required to isolate the supply so
that the external device does not back power the SIBO computer when it enters the standby state. If
the additional device does not require a supply or only uses a few microamps then Q1 and D1 can be
omitted. Vcc and the supply for the expansion device can be directly connected to Vcc2.
If CMOS level RS232 signals are required then IC1 can be replaced with a 74HC244 device. If
inverted sense RS232 signals are required, IC1 can be replaced with a 74HC241 device.
The diagram overleaf shows the circuitry for an ASICS-based 3-link with ROM.
Revision 1.00 Page 35 of 115 pages
Psion PLC (c) May 1995
The Psion SIBO Hardware Development Kit
vec
Rig
Icz vec 100K
64/128K PROM SITE E
B
ag 12Tag wy po Laz ba
ta ¥ 14 Di
AL D1
To é TS Be
Az Dz
g id Da
as DS
3 tg ba
Aa ba
id 15 DS
aS DS
20 DE
AS De }s¢ =
ay DF
ae voc voc
ag
Alo vec
AlL -
A1lz ne |S?
ars ver 4 i
Ais Pst [22 +08 ce cz
$3 rea Our /25v idon io0n
Ale. +
N
B
*
T
le t GND
GND
ND Fs
ey eee 2g
Re 100K TRL +
BCH 1 cs cz
+ 1ur/50¥ LuF/so¥
GND vee
mS 1 | s
aL
rs
82 (ita 1 ies
veo 22 [aa i wees
23 i 19° + iOurv2sy
D1 Fi 14 + ¢ 13
" 24s ex i ca
| 1 4 aa c
= vor 15 | coy yo LAZ ayes
2 t 16 7 SKT1 CASE
za 2- Fi
Teu uF 7254
BAYS? I FaHorS 7d TitN taout 2 GND SKTL
36 e _DTR
PBO Y¥ PAD TBIN TZOUT RLSD/bco|
ba PBL © pai }32 294 7 SIN TzouT 2 rs RX
4 tad Sa ei ze _Tx
x * PBZ paz [3 T4IN T40UT Tx
2 PES paz = 3 Pare DIR
PB4 paa [22 £4 R1OuIT R1IN p32 _RX__§_+ t GND
a ee PBS pas fed eno se] RZOUT R2IN Pst—Bek . DSR
PES Pas pse 25) REOUT RSIN bee—GeR 4 RTS
PE? PA? R4ouT RaIN * cts
DS, ig Te RI
* a WEE — RS0UT . RSIN * RI
PDO poco i at S|
= a PDL pci H2 24 eR ql sp }25 SIBO RS2S2 CONNECTOR
PDE pez He ibe Ria L c
BAYSS co: pea fas REG Too 100K a mMaxzan GND
12 ciolesilcizicizicis4
PDS pes
SMB PDS roe 3S
PD? pe? L414 L GND in Jin Jin Jain Jain
| 1008 R4 25 /ep zen b24 GND vovVoov¥ vo
1O5R at 27 €39 Pox GND GND GND GND GND
' CLK eSi
26 2
FOR cs2
i7q Fo s T
3g N53 PIL
cs NG BD ¢np PL2 fh
100pF iz
veo asics [8 4
GND
GND ND R?
RL 100R
100K Sue
o——___|
cL SH SPDT
vee 100n
CONNI
cer GND
SRT ee RG RS
SDS/INT BS Copuriaht CC) Psion PLO 1991
ScKS/ExON PS
Vee bs File name! CONHH DRAFT RS232.5CH
yee Bg ioorR is a 10k Braun: MG
CON COMMS CONN R20 B2xe4—Cay7 PCB Rey 1.4
100K Title
¥ 2|a
GND Rev 1.2 Move SD (pin 25 IC2> from pin 23 to 21 of Ici : EONSUMER Bases ExCeL on
Rev 1.3 Alter Ri? from 100K to 10K Size Pocument Number REV
Rev 114 Added C1io—c14 =
Rev 1.5 Moved C3 to CLK input GND GND is 6500.0008 cata
Date: June i0, i953 Sheet i oF L
Page 36 of 115 pages
1.00
1S10n
Rev
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
9. DEVICE DRIVER OVERVIEW
Introduction
Once a piece of peripheral hardware has been designed the appropriate software must be written to
control it. All hardware on Series 3/3a, Workabout and HC machines is controlled by logical and
physical device drivers. These act as the logical low-level software interface between a piece of
hardware and an application that uses it. The remainder of this document is concerned with the
methods by which a device driver is able to communicate with and thereby control an ASIC4 or
ASICS-based peripheral.
APPLICA TION SOFTW ARE
Psion C PLIB call interface
LOGICAL DEVICE DRIVER
PHYSICAL DEVICE DRIVER
PHYSICAL HARDW ARE
This chapter is intended to guide the programmer through the central issues involved in writing
device drivers for peripherals that attach to the family of Psion host machines based around the
proprietary SIxteen-Bit Organiser (SIBO) architecture. The purpose of a device driver is to abstract
away the hardware details required to conduct communication between a peripheral and a software
application that uses that peripheral. The device driver therefore performs the logical processing
required to translate low level hardware instructions into high level application services. Psion device
drivers are written in 8086 assembler and following convention are divided into a logical layer
residing over a physical layer. A physical device driver (PDD) contains the code required for talking
directly with the hardware device and provides a set of low level hardware specific services. A logical
device driver (LDD) performs the logical processing that transforms these low level services into the
high level services used by an application. This two-layer nature of device drivers at Psion can be
illustrated by the following example. An application using the serial driver decides that it requires
RTS/CTS handshaking. It calls an LDD which decides whether or not a line should be driven. If the
answer is yes, the LDD calls the appropriate PDD and asks for a particular line to be driven to a
specific state. The PDD duly carries out the requested service. Psion SIBO machines often use the
same LDD with a PDD written specifically for each version of the hardware device. In such a
situation, splitting the device driver is highly desirable. In the example given above, however, the
LDD could have talked directly with the hardware negating the requirement for a separate PDD.
Similarly, most external peripherals would normally use an LDD.
An LDD must provide a minimum of eight functions for use by the operating system. The functions
are passed to the OS via a table of function offsets (referred to as the vector function table). These
functions are mandatory. Similarly, a PDD must provide two functions for use by the operating
system and may provide more if required. An LDD will usually provide further services/functions for
use by an application. The form these take is dependent on the LDD requirements and the functions
supplied by the associated PDD(s).
Revision 1.00 Page 37 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Psion SIBO machines are supplied with a set of resident device drivers built into the ROM each of
which can be replaced with an installable device driver having the same name. Installable device
drivers can also be added to increase the number of available device drivers. Installing a device driver
is carried out dynamically without resetting the machine (this is not the case with many operating
systems).
Device Names and Channels
The name of a device driver is the mechanism by which an application can obtain a channel to that
device driver. A logical device driver name always has three characters followed by a colon. For
example, "TTy:" is the serial LDD. This name is required to uniquely identify the LDD to the EPOC
OS when attempting to open a channel on it. A physical device driver name always has the three
characters of its owning LDD followed by a period, a further three characters and a colon. For
example "TTy.UAR" is the ASICS UART driver and "TTy.srRx" is the 16450/16550 driver. The first
three characters of a PDD name are the name of the LDD to which the PDD belongs. The second set
of three characters uniquely identify the PDD. Thus in the above examples, both PDDs belong to the
"tty:" LDD.
A channel can be opened on an LDD by calling the PLIB library function p_open. EPOC uses the
driver name passed through an application p_open call to invoke the IoOpen operating system
service. This service in turn calls the associated driver open vector which can decide whether or not
to open a channel on the driver. The assembled ASIC4 Example Interface Board logical device
driver, A4EXIF.LDD, for example, has the three-character device name "LED" so a channel with its
handle in pcb may be obtained on it by means of the following call:
p_open(&pcb, "LED:", -1)
In this call, the third argument refers to the open mode and a value of -1 indicates that the mode
parameter is to be ignored. To obtain a channel on a PDD, an application should call the DevopenPpp
OS service. Typically, only LDDs open PDDs though the p_open library function can be used to open
a PDD indirectly as illustrated in the following example:
p_open(&pcb, “"TTY.UAR:", -1)
For a device driver configuration consisting of an LDD and a PDD, the application will usually open
a channel to the LDD only: the LDD as part of its initialisation would open a channel to the required
PDD. If an LDD requires a PDD and none is specified, it is up to the LDD to either fail the open
request or hunt for a loaded PDD that it can use. An LDD uses the DevFind OS service to search for
a PDD as for instance in the case of the "TTy:" device.
A device driver may be capable of supporting more than one open expansion channel at a time. In
order to distinguish the channels, a qualifier can be added to the open request as part of the device
name. It is then up to the device driver to specify the format of the qualifier. By convention,
channels are allocated a single character sequentially from the character 'A'. For example, the
parallel port driver can support two open channel, 'A' and 'B'. The LDD requires one of these
qualifiers in order to open a parallel driver channel:
p_open(&pcb, "PAR:A", -1)
p_open(&pcb, "PAR:B", -1)
The number of channels that can be thus supported will in general be dependent on the host SIBO
hardware. In the case of the serial port on the S3a, for instance, only one SIBO channel can
legitimately be opened corresponding to expansion port C. With the Workabout and HC, however, it
is possible to open up to three separate SIBO channels on ports A through to C where A refers to the
top port of the host machine, B to the bottom port and C to the side (or cradle) port.
LDDs have been designed to be accessed via the I/O system. I/O requests on the opened channel will
reach the 'strategy vector' of the device driver. PDDs have been designed to be accessed by an LDD
Revision 1.00 Page 38 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
either via far calls or the Devvector OS system service. Once a channel has been obtained on a
device driver, the operating system can send it events not sent to other applications. Examples are
events generated by the machine being switched on or off, memory segments being moved about and
the owning application being panicked. The EPOC OS can handle a maximum of 32 device drivers
on a Series3 machine and 48 on other machines.
Loadable Logical Device Driver Structure
Common features of the structure of loadable LDDs
All loadable LDDs must conform to the following rules:
e There must be a single code segment and no data segments. The code segment is encapsulated in
the assembler .asm file by calls to the codeSeg and EndCodeSeg defines respectively.
e The code segment must begin with a LibEnt structure which indicates the LDD name or
signature which is used to identify the driver when trying to open and close channels.
e There must be at least eight supported functions which are listed in the LibEnt struc.
LibEnt Structure
The first field of the LibEnt structure consists of a two-byte signature containing the define
LDDSignature or 'PDDSignature in the case of a PDD. The remaining fields consist of an eight
byte name which holds the device driver name stored as a zero terminated string (note that the
trailing colon is omitted), a two byte vector count which must be at least eight and a vector table
listing the supported device driver functions. The relevant code in the case of a hypothetical DevFunc
LDD (DEVFUNC.LDD) with the device name of "TES:" is listed below:
CodeSeg
ProcBegin@ DevFuncLDD
dw LDDSignature
db 'TES',0,0,0,0,0
dw (VectorEnd-Vector) /2
Vector:
dw DevFuncInstall
dw DevFuncRemove
dw DevFuncHold
dw DevFuncResume ; Mandatory LDD vectors
dw DevFuncReset ; must be in this order
dw DevFuncUnits
dw DevFuncOpen
dw DevFuncStrategy
VectorHandler:
dw DevFuncHandler ; Optional LDD vectors
InterruptVectors:
dw DevFuncTickInt
VectorEnd:
ProcEnd noret
The vector table contains the offsets within the device drivers code segment for the functions required
by the EPOC operating system which must be entered in the order shown. Note that in this
document, the terms vector and function are used interchangeably.
Mandatory LDD Functions
All LDDs must support the following eight functions:
@ DevFuncInstall called on device installation
@ DevFuncRemove called on device removal
@ DevFuncHold called to temporarily disable the driver
@ DevFuncResume called to enable the driver after it has been temporarily disabled
Revision 1.00 Page 39 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
@ DevFuncReset called when an application terminates without closing the channel
@ DevFuncUnits called to query the number of supported units (i.e. channels)
@ DevFuncOpen called to open a channel to an LDD
@ DevFuncStrategy called to access the driver's functionality from the I/O system
All of the eight mandatory routines pointed at by the function vector table will be called FAR by the
operating system and should therefore use a FAR return machine code instruction to return control
back to the OS. Since the FAR return address is to the OS it does not matter if the OS moves memory
whilst code in the LDD is being executed: the OS cannot move its own code.
DevFunclinstall
This function is called by the operating system when the device driver is loaded in order to initialise
any internal variables. It should not be called directly by an application process. The DevInstall
operating system service will cause this function to be called. Applications should not call this service
directly and should call instead the DevLoadLDD service.
An installable device driver may have the same name as a resident device driver. When the operating
system loads a device driver, it places it at the end of the device driver table. The operating system
will search this table for the appropriate device driver when it wishes to establish a channel. The
search starts at the end and thus will locate the most recently installed device driver (if any) or if not,
the resident driver. By this mechanism an installable driver can replace any resident driver.
When called, the DS and ES segment registers are in an unknown state. The device driver should
take whatever steps necessary to obtain direct addressability to its data. For loadable device drivers
this involves setting the DS and ES registers to the CS register or more commonly just using the CS
override. The operating system will not move memory whilst in this function, thus the normal rules
governing DS and ES may be ignored. All operating system services may be called, except those
concerning file or device access.
PASSED
No values are passed to the install vector.
RETURN
If the installation was successful, return with the carry flag clear.
If the installation failed, return with the carry flag set and the error number in the AL register.
PANIC
The install vector must not panic: it will cause an operating system kernel fault if it does.
PRESERVE
The SS, SP and BP registers must be preserved by the install function.
DevFuncRemove
This function will be called by the operating system when the device driver is requested to be
unloaded. It should not be called directly by an application process. The DevRemove operating system
service will cause this function to be called. Applications should not call this directly, they should use
the DevDelete service. Before the remove function is requested, the device driver will have received
a hold request. Thus devices will only ever be removed when in a held state. If the device driver is
currently busy serving a client, the remove request should return an error. Note that all resident
device drivers will return an error since there is no mechanism by which they can be re-installed.
When called, the DS and ES segment registers are in an unknown state; the device driver should take
whatever steps necessary to obtain direct addressability to its data. For loadable device drivers this
involves setting the DS and ES registers to the CS register. The operating system will not move
memory whilst in this function, thus the normal rules governing DS and ES may be ignored. All
operating system services may be called inside the remove vector, except those concerning file or
device access.
PASSED
No values are passed to the remove vector.
RETURN
If the remove was successful, return with the carry flag clear.
If the remove failed, return with the carry flag set and the error number in the AL register.
Revision 1.00 Page 40 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
PANIC
The remove vector must not panic: it will cause an operating system kernel fault if it does.
PRESERVE
The SS, SP and BP registers must be preserved by the remove vector.
DevFuncHold
This vector will be called by the operating system when a logical device driver is requested to be held.
The hold vector is called in the context of the operating system so DS and ES are not available. The
DevHold operating system service will cause this vector to be called. Applications should not call this
service. Physical device drivers cannot invoke holds and resumes. The operating system will call the
hold vector under three conditions:
e Device memory segments are about to be moved.
e The machine is about to switch off due to the auto switch off time-out or user request, it
enters the standby state.
e The machine is about to switch off due to the power source being removed.
It should be noted that holds and resumes are called on a per driver basis and so the corresponding
driver code must deal with all the currently open channels. In all cases the device driver must
respond to the request as quickly as possible. It must also ensure that ALL interrupts from the
hardware device that it is driving are disabled. Device memory segments can only be moved if an
installable device driver is being installed or removed. If the LDD uses an attached PDD and uses the
faster FAR call mechanism to call the PDD strategy vector, the PDD strategy vector address will
potentially move, thus the FAR address will be wrong. This address can be resolved in the resume
vector. The LDD must not call the PDD between a hold and resume. Typically, the device driver
only needs to disable its interrupts. When a resume occurs, the device driver should continue as
though nothing had happened.
If the machine is about to switch off due to the auto switch off or user request mechanisms (enter the
standby state), the device driver should make an orderly shut down of the device such that the state
before the shut down can be recovered when the system powers up again. The device driver should
also attempt to ensure that no data is lost. For example, in the serial driver the current state of the
hardware handshaking lines should be noted so that each state can be restored on power up. For this
type of power down the hold vector is allowed to take a significant length of time to shut down a
device. For example in a serial driver the hold vector should wait until the remote end stops
transmitting data after any hardware handshaking has been applied. Of course, the time taken should
be kept to a minimum: in the case of the serial driver above the time is roughly equivalent to 3
character transmission times. When a resume occurs the device driver should continue as though
nothing had happened.
If the machine is about to switch off due to the power source being removed, the device driver should
reset the device in the minimum possible time: no attempt should be made to perform an orderly shut-
down. The device driver is not expected to be able to recover the hardware state. When a resume
occurs, the device driver would typically fail any outstanding application requests. If the hold vector
takes too long the voltage will fall below the threshold to hold the state of the internal RAM. If this
occurs the machine will perform a warm re-boot when powering up, all data in the internal memory
of the machine will be lost including the device driver code! On power fail there is about 2ms
available to power down all devices.
On a power failure hold, the operating system will already have sent a 'reset' to all the SIBO serial
channels. Any device drivers using these channels need only record the hold reason for the resume
vector. Any other peripherals should be designed to allow a power fail mechanism with the minimum
amount of code. It must be noted that the power fail type hold can occur whilst the device driver is in
the memory move hold state. In this case, the device driver will receive two hold requests before
seeing a resume request. A device driver must be capable of handling this. In this case, the device
driver will also receive two resume requests. A device driver will not get a power fail hold whilst in
Revision 1.00 Page 41 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
power down hold. A call to the hold vector will always be followed by a call to the resume vector
(except when a device is requested to be removed).
Note that with the Series 3a and Workabout, there is an additional case when hold and resume must
be invoked and that is on opening/closing of the pack doors. In this case, the LDD must generate its
own Hold and Resume. This situation is examined in more depth in the context of the specific
example drivers presented later in this document.
When called, the DS and ES segment registers are in an unknown state; the device driver should take
whatever steps necessary to obtain direct addressability to its data. For loadable device drivers this
involves setting the DS and ES registers to the CS register. The device driver should not call any
operating system services in the hold vector code due to the time taken, especially on power failure.
PASSED
The AH register takes one of the following
@ DevHoldNormal Device memory is about to be moved.
@ DevHoldPowerDown The system is about to enter the standby state.
@ DevHoldPowerFail The system has lost its power supply.
RETURN
None.
PANIC
The hold vector must not panic: it will cause an operating system kernel fault if it does.
PRESERVE
The SS, SP and BP registers must be preserved by the hold vector.
DevFuncResume
This vector will be called by the operating system when the device driver is requested to be resumed.
The resume vector is called in the context of the operating system. The DevResume operating system
service will cause this vector to be called. Applications should not call this service. The resume
vector will be called either when memory has finished being moved or when the machine powers back
up. In both cases the hold vector will have been called before this vector is called. The device driver
is expected to recover from the previous hold request (except power fail) and resume any I/O that was
suspended. If the device driver has an interrupt service routine, it should reset the interrupt service
routine's address since the device driver may have moved in memory; its absolute segment address
will be different.
If the hold was a device memory segment move type hold, interrupts should be re-enabled. If the
LDD uses an attached PDD and uses the FAR call mechanism to access the PDD strategy vector, the
address of the PDD should be reset by using the DevGet PDDAddress operating system service before
enabling interrupts. Typically, the PDD will have a call back to the LDD and it needs to be informed
of the change of address of the LDD call back function, the LDD-PDD interface definition should
allow such a function request.
If the hold was a power down type hold, the resume vector needs to power up the peripheral and set it
to the state that it was in before the power down occurred. If this is not possible or data has been lost,
the device driver should inform any outstanding requests of this fact. It is also possible that the
hardware device that the driver is associated with has been removed. The driver should be able to
handle this properly. If the device driver is expected to generate events due to an external state
change, the driver should check the external state and generate appropriate events. For example, the
serial driver may be requested to inform an application when the DTR line changes state. The remote
end may have changed the state of DTR whilst the driver is held.
If the hold was a power failure type hold, the resume vector should power up the peripheral and put it
into a known state, preferably the state that the application software thinks that the device is in and
fail any outstanding requests as data is quite likely to have been lost.
Revision 1.00 Page 42 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
When called, the DS and ES segment registers are in an unknown state. The device driver should
take whatever steps necessary to obtain direct addressability to its data. For loadable device drivers
this involves setting the DS and ES registers to the CS register. All operating system services may be
called, except those concerning file or device access.
PASSED
None
RETURN
None.
PANIC
The resume vector must not panic, it will cause an operating system kernel fault if it does.
PRESERVE
The SS, SP and BP registers must be preserved by the resume vector.
DevFuncReset
This function will be called by the operating system when the device driver is requested to reset a
channel. The reset function is called in the context of the operating system so DS and ES are not
available. The device driver must request that the operating system call the reset function. This is
achieved by calling the IoRequestReset system service, usually in the open vector. To cancel this
request, the device driver should call the IoRequestResetCancel system service. The cancel service
is usually called as part of the close functionality in the strategy vector. The reset vector will be called
when the operating system is tidying up resources owned by a process that has terminated. Ifa
process terminated before it closed the device driver channel and no reset service is requested, that
channel would remain allocated; no process will ever close the channel. The reset vector allows a
device driver to reset itself and allow the channel to be opened again. Any data required to perform
the reset must be stored in the device driver. The data space belonging to the process that originally
opened the channel has been returned to the operating system memory pool and is no longer valid. If
a device driver can handle multiple channels then the data passed to the IoRequestReset system
service should identify the channel. This data will be passed in the CX register to the reset vector.
The device driver should only have a reset request outstanding with the operating system while a
process has a channel open.
When called, the DS and ES segment registers are in an unknown state; the device driver should take
whatever steps necessary to obtain direct addressability to its data. For loadable device drivers this
involves setting the DS and ES registers to the CS register or using CS override. All operating system
services may be called, except those concerning file or device access.
PASSED
This function is passed data in the CX register that the device driver requested it be sent to determine
which channel should be reset.
RETURN
None.
PANIC
The reset vector must not panic; it will cause an operating system kernel fault if it does.
PRESERVE
The SS, SP and BP registers must be preserved by the reset vector.
DevFuncUnits
This function will be called by the operating system when the device driver is requested to report the
number of units (i.e. channels) the device driver can support. This function is called in the context of
the operating system. The operating system places no significance on the number of channels a
device driver can support. It is primarily used for informational purposes. An application may use
the number of units to attempt to open any available channel on that device driver.
When called, the DS and ES segment registers are in an unknown state; the device driver should take
whatever steps necessary to obtain direct addressability to its data. For loadable device drivers this
involves setting the DS and ES registers to the CS register. All operating system services may be
called, except those concerning file or device access.
PASSED
Revision 1.00 Page 43 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
None.
RETURN
The AX register should contain the number of channels supported. If a device driver can support
multiple channels (limited only by memory constraints) then the driver may return -1. A serial device
driver, for example, might only support two channels (TTY:a and TTy:8) whereas the file device
driver can open an unlimited number of files.
PANIC
The channels units vector must not panic; it will cause an operating system kernel fault if it does.
PRESERVE
The SS, SP and BP registers must be preserved by the units vector.
DevFuncOpen
This function will be called by the operating system when a channel to the device driver is required to
be opened. This function is called in the context of the process that called the Ioopen system service.
This means that DS and ES point to the application data space. The device driver is passed two
parameters, its device handle and a pointer to an OpenEnt structure. The device handle is the entry in
the system device table of this device driver. The device driver is required to place this handle in the
ChanLibHandle field of the ChanEnt structure which must be allocated in the user's data space. The
operating system uses the device handle to route any I/O requests on the opened channel to the correct
device driver.
The OpenEnt structure contains three fields, openNamePtr, OpenMode and OpenChan.
The openNamePt r field contains a pointer to the character that exists after the device name as passed
to the ToOpen system service. For example, if the ToOpen service was passed a name of PAR:A, the
OpenNamePtr field would point to the colon. If the ToOpen service was passed a name of TTY.AS5:B
the OpenNamePtr field would point to the full stop. The device driver should process the name
appropriately, opening the correct PDD as required.
The OpenMode field contains the mode for opening the device driver. The available modes are
specified by the device driver writers. For example, a combined Xmodem and Ymodem device driver
could use the mode to specify whether the Xmodem or the Ymodem protocol is to be used.
The Openchan field contains the I/O channel handle of the device that this driver is required to
attach to. Attached device drivers are dealt with later in the chapter.
The code in a device driver open vector tends to follow a very similar pattern. This is demonstrated
by the following code fragments and associated comments. The first stage is to allocate some data
space in the calling process' heap space. This will contain the I/O channel control block:
mov cx, (size DeviceEnt)
HeapAllocateCell
jc noMemory
mov bx, ax ; cell handle
If the device driver requires a WaitHandler (described later):
mov al, (VectorHandler-Vector) /2
ToAddHandler
jc endFreeMemory
mov [bx].DriverHandler, ax
If the device driver's DevFuncReset vector is required to be called:
push bx
mov cx, ChannelIndicator 7 unique per channel
mov bx, ax ; the device handle
ToRequestReset
pop bx ; restore alloc cell
The chanEnt field of the DriverEnt structure must be initialised:
mov [bx] .DriverIo.ChanNext, bx
mov [bx] .DriverIo.ChanSignature, IoChanSignature
mov [bx] .DriverIo.ChanLibHandle, dx
The ChanNext field is used by attached drivers and will usually be set to be the allocated cell handle
of the device driver being opened. The IoFuncattach and IoFuncDetach functions manipulate these
fields. The I/O system uses this field to direct the I/O request to the correct driver.
Revision 1.00 Page 44 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
The ChanSignature field is checked by the operating system during any I/O requests for the value
IoChanSignature. If it does not contain that value, the process calling the I/O service will be
panicked for having passed an invalid I/O channel handle.
The ChanLibHandle field is used by the operating system to route an application's I/O request to this
device. The I/O request will call the DevFuncstrategy vector of the device driver.
If the driver is an attached driver the following is required:
mov cx, bx ; allocated channel
mov bx, [si] .OpenChan ; channel attaching to
mov al, IoFuncAttach ; return in BX the
ToWithWait ; channel attached to
Finally, if the channel has been successfully opened:
ele Opened Ok
ret return BX and DX
The error recovery code typically follows the following pattern:
endFreeReset:
push ax
push bx
mov cx, ChannelIndicator
mov bx, ax
ToRequestResetCancel
pop bx
pop ax
endFreeHandler:
push ax
push bx
mov bx, [bx] .DriverHandler
ToRemoveHandler
pop bx
pop ax
endFreeMemory:
push ax
HeapFreeCell
pop ax
stc
noMemory:
ret
If a device driver supports a fixed number of channels, it typically contains static control blocks. In
order to determine if a requested channel is currently open, a field should be interrogated. The device
driver should ensure that interrupts are disabled during this sort of check since a context switch could
occur and another process request the opening of the same channel. This is the classic 'test and set'
problem encountered in multi-tasking environments.
When called, the DS and ES segment registers point to the data segment of the application process
attempting to open a device channel. The application should ensure that the DS and ES segment
registers do in fact point to its data segment. The device driver must obey the normal rules
concerning segment register manipulation. The DS and ES segment registers can be reloaded if
required from the IntEnt structure pointed at by the BP register. All operating system services may
be called.
PASSED
DX contains the device handle of the device driver.
SI is a pointer to the OpenEnt structure
BP is a pointer to the IntEnt structure.
RETURN
If the channel open was successful, return with the carry flag clear and the BX register containing the
open channel.
If the open failed, return with the carry flag set and the error number in the AL register.
PANIC
The open vector can panic; it will cause the process requesting the device open to terminate. It is
however more usual to return an error to the calling process.
PRESERVE
The DS, ES, SS, SP, BP and DX registers must be preserved by the open vector.
Revision 1.00 Page 45 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
DevFuncStrategy
When an application makes an I/O request on the opened device driver channel the request is routed
to this vector by the operating system. A device driver defines the set of functions that it supports.
These typically include IoFuncSet, IoFuncSense, IoFuncRead, IoFuncWrite and IoFuncClose. A
device driver does not have to support any particular function, as it is a matter of design between a
device driver writer and application writer as to what functions and associated parameters are
provided. To obtain the power of attached device drivers, however, it is recommended that the device
driver use the system defines with their appropriate functionality, for example, the loFuncWrite
function number should always be associated with writing data.
The strategy function is passed the channel handle as allocated in the open vector in the BX register.
This typically contains control information concerning the current state of the I/O channel.
The SI register contains a pointer to a RgEnt structure. This structure contains four fields,
RqFunction, RqStatusPtr, RqA1Ptr and RqA2Ptr.
The RgFunction field contains the function number as passed to the IowithWait (or
IoAsynchronous) I/O request by the application. If a device driver does not support the specified
function, it should pass the request on to its 'parent' device driver.
The RqStatus pointer contains a pointer to a memory location in the application process's data space
that receives the I/O requests completion status. The device driver must set this memory location to
the value PendingErr whilst the I/O request is outstanding and a completion code when the I/O
request completes. An I/O request may complete within the strategy vector or it may complete some
time in the future, presumably from some interrupt.
The RgA1Ptr and RqA2Ptr fields contain the argument | and 2 parameters as passed to the
IoWithWait (or IoAsynchronous) system services. The device driver is free to specify what these
parameters are (if any).
The operating system defines a set of common function numbers used by device drivers referred to as
the IoFuncxxx set of defines. By convention, a device driver should select from this list, particularly
if some of the more advanced features of the I/O system are to be used, such as attached device
drivers. The more common defines are listed below:
@ ToFuncRead ; read from the device.
® TfoFuncWrite ; write to the device.
@ TloFuncClose ; close device channel.
@ = =ToFuncCancel ; cancel an I/O request.
® ToFuncSet ; set driver characteristics.
® tloFuncSense ; sense driver characteristics.
e lIoFuncFlush ; flush any buffers.
The PLIB library functions p_read, p_write and p_close will call the device driver with the
IoFuncRead, IoFuncWrite and IoFuncClose function numbers. Thus, if the device driver chooses
an alternative function number set, an application will not be able to use the supplied library
functions. All resident device drivers obey the following conventions:
e Acancel request will cancel any outstanding requests. A cancel request will not return any
error.
e Aclose request will ensure that any outstanding requests are completed before closing the
channel. A close request will not return any error.
e Only one request of a particular type can be outstanding at any one time. If a second request
is made the device driver will panic the calling application.
Any functions that the strategy function does not support should be passed on to the next driver down
the driver hierarchy. If the driver is a root driver (attached driver), this is achieved using the IoRoot
Revision 1.00 Page 46 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
(IoSuper)system service. If the requested function is not supported by any driver, the operating
system will return a Not Supported error.
When called, the DS and ES segment registers point to the data segment of the application process
making the I/O function request. The application should ensure that the DS and ES segment registers
do in fact point to its data segment. The device driver must obey the normal rules concerning
segment register manipulation. The DS and ES segment registers can be reloaded if required from
the IntEnt structure pointed at by the BP register. All operating system services may be called.
PASSED
BX contains the allocated channel control block.
DX contains the device handle of the device driver.
SI is a pointer to the RqEnt structure.
BP is a pointer to the IntEnt structure.
RETURN
If the function request is successful, the strategy vector should return with carry clear. A request
typically causes some I/O. If the I/O is completed by the strategy vector (i.e. the request is for a
synchronous function such as close), the completion status should be written back to the RqStatusPtr
location and the I/O semaphore signalled (using the IoSignal system service). If the request has not
yet completed (i.e. the request is for an asynchronous function), the RqStatusPtr location should
contain the value PendingErr and the I/O semaphore should not be signalled.
If the function request failed the strategy vector should return with carry set and the error code in AL.
In this case, typically no I/O requests will be completed.
PANIC
The strategy vector can panic; it will cause the process making the I/O request to terminate. In most
cases it is usual to return an error to the calling process. A major exception to this is if the calling
process makes an I/O request of the same type as one that is currently outstanding and the device
driver only supports one I/O request of a particular type at a time; by convention the device driver
should panic the calling process with the PanicIoPending panic code.
PRESERVE
The DS, ES, SS, SP and BP registers must be preserved by the strategy vector.
Interrupts and Interrupt Service Routines
Device drivers that talk to hardware tend to have interrupt service routines associated with them,
especially if they are receiving data from an external source. The EPOC operating system provides a
framework within which an interrupt service routine can be written relatively easily. An interrupt
service routine is a code section that is called by the OS in response to a particular hardware event.
As indicated in the Hardware Overview, the SIBO architecture allows for eight independent hardware
interrupt sources, some of which are pre-allocated to system components. The operating system
provides the GenSetRevector service to allow a device driver to install an interrupt service routine
for any of the eight hardware interrupt sources. This call passes the interrupt vector (the address of
the interrupt service routine) and the interrupt number (which is dependent on the host hardware) to
the OS so that it knows where to jump to when the interrupt occurs. A device driver should use this
system service and not poke directly into the 8086 interrupt vector table. The address passed to the
GenSetRevector Service is not written into the interrupt vector table but to an internal table. After
invoking this service, the desired interrupts must be masked in by writing the appropriate mask to the
mask register. Initially, of the eight interrupt sources, only the tick interrupt is masked in.
When an interrupt occurs, the microprocessor could be running any currently active process. The OS
handles the servicing of interrupts by building a mandatory operating system call frame. All CPU
registers are preserved on route. The interrupt service routine is then called as a FAR routine. Since
the operating system preserves all registers the interrupt service routine is free to use any register. As
with all interrupt service routines various rules apply:
e Interrupt service routines should execute as fast as possible. Operating system interrupt
service routines are tuned to last no longer than one millisecond.
Revision 1.00 Page 47 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
e Typically, interrupt service routines do not enable interrupts unless the routine can handle re-
entrancy.
e Interrupt service routines run in the context of whatever process is running at the time of the
interrupt. An interrupt service routine should not attempt to obtain admissibility to the
process that opened the channel but access the internal driver space only which in general is
its own code space.
e An interrupt service routine must not directly cause the OS to reschedule the running process
as this would significantly delay its completion. It must use the IoSignalByPidNoReSched system
service in order to indicate to the handler that an event has occurred to the owning process.
The handler function of the device driver must pick up the event and inform the owning
process.
e An interrupt service routine should return with the carry flag clear if it requires a reschedule
to occur (it has called IoSignalByPidNoReSched) otherwise return with the carry flag set. This
will cause the operating system to reschedule if the internal state allows such an action
otherwise the reschedule request is effectively queued until such time that the operating
system can reschedule.
At some stage during the course of an interrupt service routine, it is necessary to clear the interrupt
line with some hardware-specific action. Then the interrupt controller inside the host ASIC1 or
ASIC9 has to be cleared with a write to the NonSpecificEoi location. To remove the interrupt service
routine address, the operating system service GenResetRevector should be used. This will reset the
internal table entry to the default held in the ROM. Additionally, the interrupt mask should be reset
to the original value.
Device Driver I/O Semaphore Wait Handlers
An LDD may nominate one of its functions to be called by the operating system every time the I/O
semaphore of the process that opened the channel is signalled. The nominated function, known as the
wait handler, will only be called if the application is waiting for an outstanding I/O request to
complete. For well written applications this is practically all the time. By convention the vector table
entry after the mandatory vectors contains the handler vector. A handler routine is similar to an
interrupt service routine in that it appears to run from nowhere. Comparing handlers and interrupt
services routines shows that:
e A handler will always run in the context of the process that has opened a channel. An
interrupt service routine will run in the context of whatever process happens to be running at
the time of the interrupt.
e A handler can access the data space of the process that opened the channel. The interrupt
service routine must not. An interrupt service routine should only access the data space in
the driver which is usually its own CS space.
e A handler can cause a reschedule. An interrupt service routine must not cause a reschedule.
If it did, the interrupt would not be fully serviced (the rest of the interrupt service routine
would not be executed until a reschedule back to the process running at the time of the
interrupt, which may not happen for a significant length of time). The interrupt service
routine must only use the IoSignalByPidNoReSched to signal the channel owner.
The handler is the mechanism by which hardware interrupt events can be filtered through to the
process using the I/O channel. Typically, it is in the handler code that the 1oSignal signifying
completion of an asynchronous I/O request is invoked.
Loadable Physical Device Driver Structure
A loadable PDD must obey the following rules:
e There must be a single code segment and no data segments.
Revision 1.00 Page 48 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
e The code segment must start with a LibEnt structure.
e There must be at least two supported functions, with typically a further two defined.
Single Code Segment
A PDD must be written to contain any internal variables within its own code segment. Typically,
these variables are only concerned with unit (i.e. channel) allocation and hardware state. Data space
for a particular open channel can be allocated in the heap space of the process that opens the device.
This data space will however disappear if the process terminates, thus any variables required for
freeing the hardware after a process terminates must exist in the code space of the device driver.
The LibEnt Structure
A LibEnt structure has the following format:
e =A two byte signature
e §=6©An eight byte name
e A two byte vector count
e A vector table
The two byte signature should contain the 'PDDSignature' define. The eight byte name contains a
zero terminated name, being that of the device driver. Note that there is no trailing colon. The two
byte vector count contains the number of vectors that follow immediately after the count. There
should be at least two. For example:
dw PDDSignature ; Its an PDD driver
db "DVR.HW1',0 ; Name of the driver
dw (VectorEnd-Vector)/2 ; Number of vectors
Vector:
dw DvriInstall ; Install vector
dw DvrRemove ; Remove vector
VectorEnd:
Most PDDs also define a further two vectors:
dw DvrOpen , Open Vector
dw DvrStrategy ; Strategy vector
The table of vectors is a table of offsets within the device drivers code segment of the routines that
implement the required functionality. The vector table must have the entries in the order shown in
the example.
Mandatory PDD functions
All PDDs must support the following two functions:
@ DevFuncInstallppp called on device installation.
@ DevFuncRemovePDD called on device removal.
Most PDDs will support the following two additional functions:
@ DevFuncOpenPDD called to open a PDD.
@ DevFuncStrategyPDD called to provide PDD functionality.
All of the routines pointed at by the function vector table will be called FAR by the operating system
and should consequently use a FAR return machine code instruction to return back to the operating
system. Since the FAR return address is to the operating system, it does not matter if the operating
system moves memory whilst code in the LDD is being executed; the operating system cannot move.
DevFunclnstallPDD
This vector will be called by the operating system when the device driver is loaded to initialise any of
its internal variables. The install vector is called in the context of the operating system and not the
process that is loading the device driver. The DevInstall operating system service will cause this
Revision 1.00 Page 49 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
vector to be called. Applications should not call this directly, they should use the DevLoadPDD
service.
An installable device driver may have the same name as a currently installed device driver. When
installed, the driver is added to the end of the device driver table. When a channel to a device driver
is being established by the operating system, it searches the device table from the end first, thus the
latest installed device driver with the required name will be asked first for a channel. So as with
LDDs by this mechanism installable device drivers can replace any of the resident drivers.
When called, the DS and ES segment registers are in an unknown state. The device driver should
take whatever steps necessary to obtain direct addressability to its data. For loadable device drivers
this involves setting the DS and ES registers to the CS register. The operating system will not move
memory whilst in this function, thus the normal rules governing DS and ES may be ignored. All
operating system services may be called except those concerning file or device access.
PASSED
No values are passed to the install vector.
RETURN
If the installation was successful, return with the carry flag clear.
If the installation failed, return with the carry flag set and the error number in the AL register.
PANIC
The install vector must not panic; it will cause an operating system kernel fault if it does.
PRESERVE
The SS, SP and BP registers must be preserved by the install vector.
DevFuncRemovePDD
This vector will be called by the operating system when the device driver is requested to be unloaded.
The remove vector is called in the context of the operating system and not the process that requests
the unload. The DevRemove operating system service will cause this vector to be called. Applications
should not call this service directly; instead, they should call the DevDelete service. Before the
remove function is requested, the operating system will send a DevFuncHold request to all LDDs.
The LDD is responsible for ensuring that no activity will occur during the remove. Note that any
device driver that handles hardware interrupts must contain an LDD since only LDDs receive a hold
request. If the device driver is currently busy serving a client, the remove request should return an
error. All resident device drivers will return an error since there is no mechanism by which they can
be re-installed.
When called, the DS and ES segment registers are in an unknown state; the device driver should take
whatever steps necessary to obtain direct addressability to its data. For loadable device drivers this
involves setting the DS and ES registers to the CS register. The operating system will not move
memory whilst in this function, thus the normal rules governing DS and ES may be ignored. All
operating system services may be called except those concerning file or device access.
PASSED
No values are passed to the remove vector.
RETURN
If the remove was successful, return with the carry flag clear.
If the remove failed, return with the carry flag set and the error number in the AL register.
PANIC
The remove vector must not panic; it will cause an operating system kernel fault if it does.
PRESERVE
The SS, SP and BP registers must be preserved by the remove vector.
DevFuncOpenPDD
This function is defined as a convenience function for the LDD-PDD interface. When an application
opens a channel to an LDD, it normally uses the Ioopen system service. If the name specifies, or the
LDD requires, a PDD then it needs to open a channel toa PDD. The Devopenppp system service will
call this PDD vector to establish a channel. The LDD now has a choice of calling a PDD vector using
the DevVector system service or calling the fourth vector in the vector table directly. The fourth
Revision 1.00 Page 50 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
vector is assumed to be a strategy vector to which any parameters as required by the LDD-PDD
interface can be passed. The FAR address of the strategy vector is returned by the
DevGetPDDAddress. When an LDD receives a DevFuncResume it should call DevGet PDDAddress
again to ensure that if the PDD has moved the LDD still has its correct address. As a design, a PDD
could provide many vectors, one for each required function. The LDD would then use the Devvector
system service to access each of these functions. The DevGetPDDAddress will only return the FAR
address of the fourth vector.
When called, the DS and ES segment registers point to the data segment of the application process
making the open function request. The application should ensure that this is indeed the case. The
device driver must obey the normal rules concerning segment register manipulation. All operating
system services may be called.
PASSED
The BX register contains a pointer to the PDD unit name. The pointer passed to the DevOpenPDD
service is used to find the PDD device to open. The BX register is loaded with a pointer to the
trailing colon (if any) in the PDD unit name. For example if the name "TTy.AS5:A" was passed to
the DevOpenPDD service, BX would contain a pointer to :A upon calling the open vector.
RETURN
If the open was successful, return with the carry flag clear.
If the open failed, return with the carry flag set and the error number in the AL register.
PANIC
The open vector can panic; it will cause the process requesting the device open to terminate. It is
however more usual to return an error to the calling process.
PRESERVE
The SS, SP and BP registers must be preserved by the open vector.
DevFuncStrategyPDD
This function is defined as a convenience function for the LDD-PDD interface. Typically, all
application function requests are routed through the strategy vector. To speed the calling interface,
the DevGet PDDAddress operating system function will return a FAR address of this vector. The
device driver writer defines all the functions and return values as required.
When called, the DS and ES segment registers point to the data segment of the application process
making the function request. The application should ensure that the DS and ES segment registers do
in fact point to its data segment. The device driver must obey the normal rules concerning segment
register manipulation. All operating system services may be called.
PASSED
The parameters passed are defined by the device driver write.
RETURN
All returns are defined by the device driver writer.
PANIC
The strategy vector can panic; it will cause the process requesting the function to terminate. It is
however more usual to return an error to the calling process.
PRESERVE
Which registers are preserved is defined by the device driver writer.
Revision 1.00 Page 51 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
10. ASIC4/ASIC5 BASED DEVICE DRIVERS
Introduction
This chapter describes the rules and problems involved in writing a device driver that controls some
form of ASIC4 or ASICS based hardware. Details concerning the internal organisation of these
ASICs were presented earlier in chapters 6 and 7. The emphasis is on their use for Series 3a
applications, though most issues that will be discussed also apply to the Series 3, MC and HC range of
Psion products.
In addition to the eight mandatory functions already detailed in the Device Driver Overview chapter,
an LDD will usually provide additional functionality in the form of further vector table entries
dependent upon the requirements of its application. Wherever possible, these functions should make
use of the various pre-defined system defines for services such as reading (p_read) and writing
(p_write) etc. It should be noted that there is no particular requirement to implement a device
driver as a separate PDD and LDD and in the case of the example logical device driver
A4EXIF.LDD, the approach taken is to incorporate both aspects into the one LDD.
SIBO Hardware Expansion Channels
The number of SIBO expansion channels supported by the host machine will vary according to the
particular Psion hardware present. So that a single device driver may be compiled for the different
host machine possibilities, a number of build flags can be used to set various constants within the
include files. The hardware options are outlined in the table below:
SIBO Machine Flags | Number of SIBO serial channels supported Machine Build Flag
Consumer (S3a) Refers to $3a with ASIC9 only. Supports 1 SIBO channel
(A)
ES ae Mat AST lysed SPS PTT
It should be noted that Psion device drivers should be designed to be easily adapted from machine to
machine. For a well-written driver, the only change that needs to be made in adapting it for use on
another Psion machine is the alteration of the build flag at the start of the code. This flag indicates to
the compiler which SIBO machine flags as well as other variables should be set for the host machine.
The four most important SIBO machine variables are the channel interrupt mask, the channel
interrupt number, the channel interrupt vector and the hardware SIBO channel. The channel
interrupt mask is an eight bit value or'd with the contents of either AlInterruptMask or
A9BInterruptMask (the mask registers) to initiate interrupts on the relevant channel depending on
whether the interrupt controller resides in ASIC1 or ASIC9. If this mask is then used in a
HwGetChannel call, any hardware interrupts on the selected expansion channel will be directed to the
appropriately coded interrupt service routine. The channel interrupt mask is also required in the
subsequent HwFreeChannel OS service call and when stopping hardware interrupts. The channel
interrupt number is a sixteen-bit quantity required by the GenSetRevector and GenResetRevector
OS system services to indicate to the OS which default interrupt service routine is to be replaced by
the suitably coded device driver interrupt vector. The channel interrupt vector is a sixteen-bit
pointer to the location of that interrupt vector in the device driver code. Finally, the hardware SIBO
channel is used by the HwSelectChannel OS service to direct any SIBO serial control or data frames
Revision 1.00 Page 52 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
along the appropriate channel. The situation regarding the value of these variables for the expansion
ports on all current SIBO platforms is illustrated in the table overleaf:
IW orkabout (Series3)
a en en an
Channels
Controller ASIC |ASIC? ASICO
Mask Register A9BInterruptMaskRW a a a ae
IHwIrq2Revector
mask A9MExpIntA
(Expansion Port A)
mask A9MExpIntB
(Expansion Port B)
Imask AOMSlave
(Expansion Port C)
IHwIrq4Revector
IHwIrgq5Revector
IHwIrq2Revector
ASIC2
mask ExpIntLeftA
(Expansion Port A)
mask ExpIntRightB
(Expansion Port B)
mask Asic2Int
(Expansion Port C)
IHwIrgq3Revector
IHwIrq2Revector
IHwIrq4Revector
ASIC2 ASIC2
mask Asic2Int
(Expansion Port C)
mask ExpIntLeftA
(Expansion Port A)
mask ExpIntRightB
(Expansion Port B)
IHwIrgq3Revector
IHwIrq2Revector
IHwIrq4Revector
Ptr
Channel SelectChannel5. SelectChannel3 IExpChannelLeftA IExpChannelLeftA SelectChannel7
Hard Select SelectChannel4 ExpChannelRightB = |ExpChannelRightB
arOWAre Dre SelectChannel5 SelectChannel7
Talking to ASIC4
All communication to an ASIC4 is via a Psion Serial Link. As explained in the chapter on the SIBO
serial protocol, two forms of data can be sent and received along this channel. These are control and
data bytes. Control bytes give specific instructions to ASIC4 and data bytes can either be data sent to
or from ASIC4 or data given to or taken from peripheral chips in ASIC4's address space. Sending
and receiving control and data frames down a Psion Serial Channel from a Series 3/HC host is simply
a matter of IN and OUT instructions to various fixed I/O addresses. Various assembler macros have
been set up to ease this task and provide machine independence and they are detailed in the appendix.
These include:
SCONTOUT Output the control byte held in the AL register
SDATAIN Input a byte of data and place it in AL
SDATAOUT Output the data byte in the AL register
XNOP Wait a short while
SBUSY Wait while the Psion Serial Link is busy
Once a piece of peripheral hardware has been designed the appropriate software must be written to
control it. All hardware devices on Series 3/3a, Workabout and HC machines are controlled by device
drivers. These act as an interface between a piece of hardware and an application that uses it. The
following section goes into further detail regarding the methods by which a device driver is able to
communicate with and thereby control an ASIC4 and ASICS based peripheral.
ASIC4 Registers
ASIC4 has eight registers and their functions in mixed (i.e. peripheral) mode are outlined below:
Register 0: This register is the read/write Data Register that controls the data lines DO-D7 which are
normally in tri-state mode. Data written to the Data Register is output on DO-D7 during a write cycle
and data input to the DO-D7 may be read from the register during a read cycle. On reset, this register
holds the Info Byte and its bits have the following meanings:
Revision 1.00 Page 53 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Bit No. D7 D6 DS D4 D3 D2 DI DO
DD DN N S S _ S
D D_ OD i _ Device type
0 0 O RAM SSD
0 oO 1 Intel Flash type 1
0 1 O Intel Flash type 2
Oo 1 1 TBS
1 0 O TBS
1 0 1 TBS
1 1 0 Read only SSD (ROM OTP etc.)
1 1 1 Hardware Write protected SSD
N N Number of devices
0 O 1
0 1 2
1 0O 3
| ae | 4
S S_ S__ Device Size
0 O O Illegal (Indicates no SSD present)
0 0 1 32Kbyte
0 1 O 64Kbyte
Oo 1 1 128Kbyte
1 0 O 256Kbyte
1 0 1 512Kbyte
1 1 O 1Mbyte
1 1 1 2Mbyte
Register 1: This register is both a read and write register. In read mode, it is termed the Input
Register. The eight bits of this register are then defined as follows:
The Se, De and Ne bits hold, on reset, the Extended Info Byte which is used in ASIC4 Extended mode
to define the type of peripheral device as explained later in the section on ASIC4 reset and
configuration and outlined below:
M De Ne Se
1 0 0 90 No peripheral devices
1 0 O 1 Turbo RS232 serial (16550)
1 oO 1 O 3Fax
1 oO 1 1 T.B.S.
1 1 0O 0 T.B.S.
1 1 OO 1 T.B.S.
1 1 1 O T.B.S.
1 1 1 1 Extended info contained in ROM.
The X2 bit sets the state of the X2D2 input which is used to indicate whether the device size is
correct. In M=0 mixed mode, the X2 bit must be low. Inputs In0-In2 hold the current status of the
three correspondingly named general input lines to ASIC4.
In write mode, Register 1 is termed the Device Size Register where bits 3-0 (S3-SO) map to the
settings of the decoder inputs (and hence the peripheral device size) as follows overleaf:
Revision 1.00 Page 54 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Size Register Decoder Inputs Device Size (bytes)
S3 S2 S1 SO DCO DC1 DC2
0 0 0 0 A15 Al6 Al7 32k
0 0 0 1 Al15 Al6 Al7 32k
0 0 1 =O Al6 Al7 A18 64k
0 oO 1 1 Al7 Al18 A19 128k
0 1 0 0 Al8 Al19 A20 256k
0 1 0 1 A19 A20 A21 512k
0 1 1 =O A20 A21 A22 1M
0 1 1 1 A21 A22 A23 2M
1 0 0 0 A22 A23 A24 4M
1 0 O 1 A23 A24 A25 8M
1 0 1 O A24 A25 A26 16M
1 oO 1 1 A25 A26 A27 32M
1 1 0 0 A26 A27 0 64M
1 1 0 1 A27 0 O 128M
1 1 1 = O 0 0 O 256M
1 1 1 1 0 oO O Not Used
This register defaults to OxOf on reset (i.e. not used).
Register 2: A write to this register , the Address Increment Register, will increment the addresses
AO-A3.
Register3: This register is the write-only Address Register which controls all 28 address lines (AO-
A27) directly and the eight chip selects (CSO-CS7) indirectly. The address register is written to in
multi-transfer mode LSByte (ATO) first. There can be up to four bytes written:
Byte Address lines
ATO AQ - A7
ATI A8& - Al5
AT2 Al6 - A23
AT3 A24 - A27
When the first byte is written, all the higher address lines (A8-A27) are reset to 0. Bits 4-6 of AT3
may be used by the internal address decoder to control the CS outputs CSO-CS3 if appropriate. On
reset, all bits of this register are cleared.
Register 4, 5 and 6: Not implemented.
Register 7: This register is the write only ASIC4 Control Register and holds the following bits:
Bit: 7 6 5 4 3 2 1 0
Label: LBO TSTA LTM VPS EDA CSS WRS OES
Setting the LBO and VPS bits causes the corresponding lines on ASIC4 to be set high enabling them
to be used as general purpose outputs for peripheral development. OES and WRS control R/W
accesses.
Additional ASIC4 Signals
InO, In1, In2 are general purpose digital inputs. LBO, VPS are general purpose digital outputs. OE,
WR control Read/Write bus accesses. MCSD, X2D2 should be tied to ground via a 100k resister.
POR is the reset line.
Revision 1.00 Page 55 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Talking to ASIC5
The Psion serial protocol was designed to allow many different peripheral ASICs to lie on the same
serial channel. Before software can communicate with an ASICS it must first be selected. ASICS
must be selected in different ways depending on whether it has been configured (in hardware) to
operate in either Pack or Peripheral mode. In addition to selecting ASICS when it is first used,
ASICS must be re-selected whenever a hold and resume is generated due to power down, pack doors
opening or when the peripheral is inserted or removed. ASIC5 will always respond to a select with a
byte indicating what type of peripheral or pack it is. If there is no ASICS connected to the Psion
serial link there will obviously be no response (zero is returned) and software must then take the
appropriate action. To select a peripheral mode ASICS the following code can be used:
HwNullFrame
mov al, (SerialSelect or Asic5NormallId)
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
test al,al
je NoASIC5PeripheralOutThere
To select a pack mode ASICS the following code can be used.
HwNullFrame
mov al, (SerialSelect or Asic5PackId)
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
test al,al
je NoASIC5PackOut There
Note that an ASIC4 can pretend to be an ASICS in pack mode and will respond appropriately.
ASIC5 Registers
ASICS has sixteen internal registers. To read or write from an ASICS register takes two steps. First
a control byte must be sent along the Psion serial link to select which register. This should be
followed by a read or write of the appropriate data value. The sixteen registers are listed in the table
below. Some can be read and written to and some are read or write only.
| oO | URW PortAreadandwritedata
| 6 | RW Interrupt Maskread and write
| 8 | RW __| UART Status/UART Control register
| 9 | R/W_| UART Receive/UART transmit holding register_|
UART Baud rate LSB
| 13) | OR Barcodereaddata
| 4 {| ER Synchronous Port2read
Revision 1.00 Page 56 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Reading from the Port A register causes ASICS to generate a memory access cycle. The value read
from port A will be the value retrieved from any attached memory or memory mapped peripheral.
Writing to Port A will cause ASICS to generate a write cycle and write the supplied value to attached
memory. In both cases the address used for the access will depend on ASICS's mode and the
configuration of ports B, C, and D. If the UART is enabled (Bit 0 of the port B mode register)
memory cannot be accessed because port A lines are reused.
Writing to port B will cause the value written to be latched onto the output lines PBO-PB7 (which
form address lines AO-A7 for memory access cycles). Reading from this register will return the last
value written.
Writing to the port B mode controls various aspects of ASIC5 behaviour. The table below indicates
the meanings of each bit in the register. When set to operate in counter mode the value output on
lines PBO-PB7 can be incremented by reading from the port B mode register, post-incremented by
reading or writing to the port A register or cleared to zero by writing to the Port D and C register.
| 0 _| 0, Memory mode. 1, Peripheral mode -enables UART____|
| 6 NotUsed
— a
7 Not Used
POT | Countermode
POT Latch mode
Pot | Baud rate outon portB
When ASICS is in pack mode the first write to the port D and C register will be latched onto lines
PDO-PD7. In multiwrite mode the second and subsequent data writes will be latched onto port C with
the following bits in the register forming the following functions.
| Databit_ | Pin, | Function _|
a |
The bit SELO and SEL1 determine which chip select is used when a memory access cycle is generated
by accessing port A. CSO-CS3 are selected as follows.
CSO
CS2
=
Revision 1.00 Page 57 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
In peripheral mode a write to the port D and C register will latch the value written onto lines PD1-
PD7. In peripheral mode the line PDO forms the UART TX line. Setting bit zero in the port C and D
register therefore has no effect.
ASICS is capable of generating an interrupt due to various external events. The interrupt mask
register is used to select which events will generate an interrupt. Writing to the interrupt mask
register will set the mask to the value written. Reading the interrupt mask register will return the
current mask. The meanings of each bit in this register is given in the table below. Setting an
appropriate bit to 1 will enable that events interrupt, clearing to 0 will stop that event from causing an
interrupt. On reset all events are disabled.
Bit
| OP UART CT UART character received
Synchronous port] character received
Synchronous port2 character received
| 6 [PCA Barcode data/general interrupt
When an interrupt occurs reading the Interrupt Status register will indicate the source of the interrupt.
The meaning of each bit corresponds directly to each bit in the interrupt mask (see table above). A
high bit indicates an active interrupt event.
Reading the Barcode data register returns a byte representing the states of the following lines.
Communicating with ASIC4
ASIC4 is capable of operating in several modes. Attached peripherals can contain an ASICS chip
instead of an ASIC4. Before talking to an ASIC4 you must first ensure that there is an ASIC4 at the
end of your serial link and you must set ASIC4 into the correct operating mode. You must do this
when the channel is first obtained to ensure you have the right peripheral to start with, and also
whenever you get a Hold and Resume due to a power down, Pack doors opening, or the peripheral
being removed. You should also check the peripherals ID to check what peripheral it is. The user is
more than likely to pull out your I/O port and replace it with a 3Fax in mid operation. You select
ASIC4 in the correct mode by sending a special control code. If there is an ASIC4 out there it will
respond by sending back a non zero value. The peripherals ID can be read back from ASIC4's info
register. This register also returns the state of the input lines INO, IN1, IN2. The coding example
below shows how ASIC4 can be checked for, selected and the peripheral ID checked:
HwNullFrame
mov al, (SerialSelect or Asic4Id) ; First look for an
SBUSY ; ASIC4 at the other
SCONTOUT ; end of the link
XNOP
Revision 1.00 Page 58 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
SBUSY
SDATAIN
test al,al
je NoAnASIC4IsItAnASIC5
mov al, (SerialReadSingle or A4InfoR) ; Now see if we
SBUSY ; have the right
SCONTOUT ; peripheral
XNOP
SBUSY
SDATAIN ; Mask out the unwanted
and al,0Of0h ; bits
cmp al,PERIPHERAL_ID ; check for correct ID
jne IsASIC4ButNotRightPeripheral ; Got our peripheral
ele ; Connection Okay!
ret
IsASIC4ButNotRightPeripheral: + Is an ASIC4 but not
popt ; the right peripheral
stc ; Connection Failed!
ret
NoAnASIC4IsItAnASIC5: ; No ASIC4
mov al, (SerialSelect or Asic5NormallId)
SBUSY ; Could have been an
SCONTOUT ; ASIC5 so try to put
XNOP stc ; back in the
right mode
ret ; Connection Failed
Bits in ASIC4s info register have the following definitions:
Pot | Dmsb | DT Wiss | TN? TN NO
Sending and Receiving data using ASIC4
All ASIC4 peripherals are memory mapped into that ASIC's address space. To access a peripheral or
a particular peripheral's register the ASIC must first be told to set its address bus to the appropriate
location. Once it has been informed of the address which it is to access that location can be read from
or written to as many times as required. The value to be written is held in the data register. To read
or write to another location the address that the ASIC is accessing must be changed. To read from a
random address within the ASIC's address space the sequence would be:
1) Send a control code to inform the ASIC that it is to set its address bus to the following address.
2) Send the address to position to.
3) Send a control frame to inform the ASIC that we wish to read from this address.
4) Read back the byte.
To write a random value to and address within the ASIC's address space the sequence would be:
1) Send a control code to inform the ASIC that it is to set its address bus to the following address.
2) Send the address to position to.
3) Send a control frame to inform the ASIC that we wish to write to this address.
4) Send the byte.
Overleaf are two 8086 assembler functions Input and Output which read from or write to an address
within the ASIC's address space. These functions only give access to the bottom 256 addresses. For
peripheral devices this is usually more than adequate. Interrupts should always be off during calls to
these functions to prevent the S3/S3a/HC from multitasking. Note that in the following routines,
A4Address and A4Data refer to the value of the respective ASIC4 registers. SerialWriteSingle has
the value corresponding to a single frame write in the SIBO serial protocol format. These system
defines can be found in the important include files ospack.inc and ossibo.inc.
ProcBegin@ Output
;
;
; Output byte to ASIC4-based peripheral
; IN: DL holds the hardware address ASIC4 is to write to
Revision 1.00 Page 59 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
; AL holds the byte to be output to that address
push ax
mov al, (SerialWriteSingle or A4Address) ;CTRL=Write to A4 address
reg
SBUSY
SCONTOUT ;Send this control
frame
mov al,dl ;DATA=Hardware address
SBUSY
SDATAOUT ;Send this data
frame
mov al, (SerialWriteSingle or A4Data) ;CTRL=Writing data
now
SBUSY
SCONTOUT ;Send this control
frame
pop ax ;DATA=Data to write
SBUSY
SDATAOUT ;Send this data
frame
ret
ProcEnd noret
ProcBegin@ Input
; Input byte from ASIC4-based peripheral
7 IN: DL holds the hardware address ASIC4 is to read from
; OUT:AL holds the value read from that address
mov al, (SerialWriteSingle or A4Address) ;CTRL=Write to A4 address
reg
SBUSY
SCONTOUT ;Send this control
frame
mov al,dl ;DATA=Hardware address
SBUSY
SDATAOUT ;Send this data
frame
mov al, (SerialReadSingle or A4Data) ;CTRL=Reading data
now
SBUSY
SCONTOUT ;Send above
control frame
SBUSY
XNOP
SDATAIN ;Receive data frame
ret ;AL holds the data
ProcEnd noret
Obtaining and using a channel
The s3/S3a/HC have three Psion serial links. Only one of these channels can be selected for
communication at any one time. Two of these channels form the SSD slots. The third forms the
expansion port. Before a device driver is able to talk to a peripheral it must both own and have this
third channel selected. Many device drivers can exist in memory and more than one may access the
peripheral. To prevent multiple access to a single peripheral a device driver must first own a serial
channel before it is free to communicate to the ASIC4/S peripheral at the end of it. To check if a
channel is free and then reserve it call the operating system function HwGetChannel. This will return
with carry clear if the attempt to capture the channel was successful, carry set otherwise.
mov al, InterruptMaskForDesiredChannel
HwGetChannel
jc CouldntGetTheChannel
Obtaining the desired channel will usually be performed by a device drivers open vector. Open
should fail if the channel is unavailable. If a device drivers takes possession of a channel it is its duty
Revision 1.00 Page 60 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
to free it again once it is finished. This would normally be done when the device drivers is closed and
is performed by the operating system function HwFreeChannel.
mov al, InterruptMaskForDesiredChannel
HwF reeChannel
As illustrated in the above table, on a series 3a the interrupt mask for the expansion port (Port C) is
defined by A9MSlave, on a series 3 Asic2Int. Interrupts are IRQ2 and IRQ4 respectively. Only one
serial link can ever be selected at one moment in time. Selecting a particular channel means that you
are unable to speak to another without selecting it instead. To select a channel the operating system
call HwSelectChannel is used.
mov al, SelectForDesiredChannel
HwSelectChannel
push ax
HwSelectChannel will return in al the channel that was previously selected. Device drivers should
select the correct channel on entry to any vector or interrupt service routine that needs to
communicate down that channel. On exit the previously selected channel should be restored.
Between the time when the channel is first selected and when the old channel is restored multitasking
should be disabled. this will usually mean switching off interrupts. Because of the watchdog timer,
interrupts cannot be left off for an indeterminate length of time. Communications down channels
therefore will usually be restricted to short bursts. For the expansion port the channel to select on an
S3a is defined by Select Channel5 on an $3 SelectChannel7.
pushf
eli
mov al, SelectChannel5
hwSelectChannel
push ax
mov dl, AddressOfInputBuffer
call Input
mov dl, AddressOfOutputBuffer
call Output
pop ax
hwSelectChannel
popf
Controlling ASIC5's UART
Before data can be sent or received from ASIC5's UART continuous clocking from the host must be
enabled and a baud rate selected. The UART must be enabled by setting bit 0 in the port B mode
register. The selected baud rate value is related to the result of dividing the required baud rate into
the input clock frequency from the host of 1.536 MHz. The value generated from the equation given
below forms a sixteen bit word. ASICS has two registers for selecting the baud rate. Register 10
should contain the least significant byte and register 11 the most significant byte of the calculated
word value. The table below lists the divisor values for some of the more commonly required baud
rates:
Divisor = 1-(96000/Desired Baud Rate)
9600 a ee ae ee
7200 fff
4800
Revision 1.00 Page 61 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
The format of data communicated, stop bits, data bits, parity checking, is controlled by writing to the
UART status/control Register. Bits in the UART status/control register have the following meanings:
| 0 | Stateof the CTS line (PAI) ___| Generate break character
iar
A character to be transmitted should be written to the Transmitter Holding Register where ASICS will
convert it to serial form for transmission. The register will be emptied once the character has been
transmitted. ASIC5 contains no internal buffering. The Transmitter Holding Register must be empty
before writing a character to it. The state of the Transmitter Holding Register is reflected in the
Transmitter Empty bit in the UART status register. Enabling the Transmitting Holding Register
interrupt will cause ASICS to generate an interrupt every time that the Transmitting Holding Register
becomes empty. Reading the UART Status Register will clear the interrupt. Received characters are
copied into the Receive Character Register. If the Receive Character Interrupt is enabled ASICS
generates an interrupt on each character received. If the character is received in error due either
parity, framing or overrun errors, appropriate bits in the UART Status Register are set to reflect this.
Hold and Resumes
There are three types of hold and resume. The first occurs when memory is being moved. An LDDs
hold and resume vectors will always be called when this occurs. The second is a On/Off Hold and
resume. An LDD will always be held and resumed when this occurs although it is not guaranteed that
power will have been restored to the expansion ports when the resume is issued. The third type
occurs when one of the pack doors is opened or a peripheral inserted. Only certain internal LDDs
receive a Hold and Resume under these circumstances. Any loaded LDD will definitely not receive a
Hold or Resume. To get around these problem, the TcK: device driver is used to provide a regular
call to a routine within your driver. This call monitors the power to the expansion port and issues its
own holds and resumes as appropriate. Holds and resumes can become nested and the whole situation
can become rather complicated. The correct procedure for dealing with holds and resumes for an
ASIC4 peripheral device driver (LDD) is given below.
When a hold is received through the normal route the channel is marked as being under a normal
hold. If the polling routine sees that the power has vanished and the channel is not already under a
Revision 1.00 Page 62 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
normal hold then it holds the channel and marks it as being under a special hold. If a normal resume
is issued channel can be resumed but only if power is present. If power is not present then the
channel is marked as being under a special hold and the resume is put off. If the polling routine sees
that the power is present and that the channel is under a special hold then it should resume the
channel.
Alternatively of course each time you read and write to your peripheral you could do a quick pre-
check to see if the hardware is available and set-up correctly. This would dispense with the need to
handle power up/down or pack door holds and resumes. You would still have to start and stop
interrupts though when appropriate.
Example Device Drivers
An example device driver which will control the ASIC4 Example Interface Board described earlier
can be found in the file A4EXIF.ASM. The device driver is a fully comprehensive multi-channel
implementation. It supports all the mandatory logical device driver functions. Open will fail if the
Interface Board hardware is not present. It has an interrupt service routine and handles Holds and
Resumes correctly in all the distinct cases outlined earlier. In addition, asynchronous reads of the
LED status are possible so a special routine to handle this case, the Wait Handler, is included. The
driver has been made as fully comprehensive as possible both in terms of functionality and the choice
of host machine. To this end, the code given can be compiled for the entire range of Psion machines
simply by changing the appropriate machine Build Flag at the head of the file which then causes the
correct interrupt masks to be selected for the machine. Chapter 11 of this document details the
structure of A4EXIF.LDD a logical device driver constructed for the ASIC4 Example Interface Board.
Chapter 12 details the functionality of a physical device driver for the ASIC5-based Psion 3-link
peripheral that enables the host hardware to communicate with a PC by converting SIBO serial
protocol signals into RS232 signals. Once again, this driver contains various build flags to facilitate
conditional compilation. Common interrupt routine code is included and the LDD-PDD interface is
specified.
The source code for both A4ZEXIF.LDD and SYS$AS5.PDD is presented in the appendix to this
document.
Revision 1.00 Page 63 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
11. AN EXAMPLE DEVICE DRIVER FOR ASIC4:
A4EXIF.LDD
Introduction
In this chapter, the functionality and code structure an example installable logical device driver,
A4EXIF.LDD, is presented in some depth. Circuit details of the corresponding Psion peripheral for
this driver, the ASIC4 Example Interface board, were outlined in chapter 8. A4EXIF.LDD enables
software written using the Psion SDK to communicate with the prototype ASIC4 Example Interface
board through means of standard PLIB calls such as p_open' and 'p_write. The description of
A4EXIF.LDD is intended to provide a clear insight into the generalised structure of logical device
drivers for peripherals based around the SIBO architecture. To this end the actual usefulness of the
combined hardware-driver interface is of secondary importance. As shown earlier, the ASIC4
Interface Board translates SIBO serial protocol signals into a parallel 8-way data bus format which
can be used to set various 74HC series latches and gates. An eight-bit buffer and latch are commoned
to eight LEDs. The latch is write-only and is used for setting the state of the LEDs. The buffer is
read-only and is used to sense the state of the LEDs. In addition, a facility for generating hardware
interrupts is provided by means of a suitably connected switch and third 8-way buffer (the status
buffer). Address decoding is provided by two 2-to-4 decoders attached to address lines AO and Al.
Code Structure
Loading A4EXIF.LDD and Device Names
A4EXIF.LDD is loaded into the RAM of the host machine by means of the following PLIB call in the
application code:
p_loadldd ("A4EXIF.LDD") ;
The name of a device driver is the mechanism by which an application can obtain a channel to that
device driver. LDDs all have three character names which are stored in the second field of the
driver's LibEnt structure followed by a colon. This name is required to uniquely identify the LDD to
the OS when attempting to open a channel on it. The A4EXIF LDD has the three character name
"LED" so a channel with its handle in pcb may be obtained on it by means of the following call:
p_open (&pcb, "LED:",-1);
EPOC used the driver name in the p_open call to invoke the ToOpen system service which in turn
invokes the Open vector on the associated device driver.
The Single Code Segment and Data Storage
As indicated earlier, loadable Psion device drivers have a single code segment and no data segment.
Data associated with the driver is stored in one of two distinct ways dependent on its nature. Global
data associated with the driver is stored in its code segment. Examples of such data are the channel
interrupt masks and numbers have to be visible to all processes that may be using A4EXIF.LDD.
Data local to the application invoking the driver, however, is stored in the heap space of that
application. An example in A4EXIF.LDD would be the pointers to the open channel strategy vector
parameters.
The overall structure of the code segment is typical of Psion logical device drivers. The code segment
begins with a CodeSeg directive followed by the LibEnt structure which defines the mandatory device
driver functions as well as two non-mandatory ones. These are the Wait Handler and the replacement
Revision 1.00 Page 64 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Tick Interrupt Vector. Before entering the code for these functions, all global variables are declared
in what is termed the device driver's internal data space. Following the code for the Lib Ent functions
comes the code for all the local driver functions. After these are the EndCodeSeg and end A4ExifLDD
directives.
Channel Status Ent and Open Channel Control Block
At the head of the driver's assembler source file A4EXIF.ASM, various constants, compiler defines
and type definitions are listed. It is here that templates are declared for the global structures that hold
the key driver variables. In view of the above discussion, most device drivers employ at least one
globally defined structure to hold the various important flags and masks that relate to the status of
each separate channel on that driver. In the case of A4EXIF.LDD, two different structure types are
employed, namely A4ExifStatusEnt and A4ExifEnt. The former is referred to in this chapter as the
StatusEnt struc and is instantiated later on in the device driver code segment with each separate
permissible channel of the main Psion host machines being assigned its own StatusEnt struc. A
channel's StatusEnt struc is generally accessed through CS:DI and holds important channel-related
information such as the A4ExifChannelOpen and A4ExifChannelRunning flags and the channel
interrupt masks and interrupt numbers. The StatusEnt structure resides in the driver code segment
whereas the A4ExifEnt struc is held in the heap space of the application invoking the driver and so is
accessed through DS:BX. The A4ExifEnt structure contains a number of variables that are logically
associated with a successfully opened channel and as such should be distinguished from the StatusEnt
variables. An A4ExifEnt struc instantiated by invoking the device driver's open vector is referred to
as the open channel control block and it is generally accessed through DS:BX.
The layout of both the StatusEnt struc and the A4ExifEnt open channel control block struc are
presented later in this chapter along with various other important pre-defined structs that were used in
the construction of A4EXIF.LDD. Both of these structures were extensively used in the coding of the
LDD functions described in the following pages.
SIBO hardware and conditional compilation
The number of expansion channels supported by a host SIBO machine is dependent on the hardware.
In the case of the S3a, only one SIBO channel can legitimately be opened corresponding to expansion
port A. With the HC and Workabout, it is possible to open up to three separate SIBO channels on
ports A through to C. In A4EXIF.LDD, a global constant numberofchannels 1s set at the start of the
device driver code segment to indicate the number of serial SIBO channels supported by the different
machines. This will vary according to the Psion hardware present and in order to aid conditional
compilation of the A4EXIF driver for the different host machine possibilities, a number of build flags
can be used to set various constants within the include files. The hardware options with regard to
these flags were outlined in the previous chapter.
It should be noted that Psion device drivers should be designed to be easily adapted from machine to
machine. With the A4EXIF driver, for instance, the only change that needs to be made in adapting it
for use on another Psion machine is the alteration of the build flag at the start of the code segment.
This flag indicates to the compiler which SIBO machine flags as well as other variables should be set.
The SIBO machine flags are in turn used later in the code segment header to set the global
numberofchannels variable mentioned above. For example, in A4EXIF.LDD, we have the
following:
if Corporate or Workabout
numberofchannels equ 3
else
endif
This type of code is used extensively in the conditional instantiation of A4ExifStatusEnts in the
device driver's internal data space. Here different interrupt masks and SIBO channels are invoked for
the different machines according to the host controller ASIC. For instance, in the case of a consumer
(S3a), the hardware interrupt mask corresponding to expansion port C on an ASIC9 is mask
A9MsSlave and the interrupt number is HwIrq2Revector. On an Workabout, the masks for expansion
Revision 1.00 Page 65 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
ports A, B and C are A9MExpIntA, A9MExpIntB and A9MSlave respectively. The corresponding
interrupt numbers are HwIrq4Revector, HwIrq5Revector and HwIrq2Revector. This conditional
compilation code in A4EXIF.LDD outlined here is worthy of some study because it encapsulates all
the information regarding masks and SIBO hardware channels required by the prospective developer
interested in constructing a multi-platform Psion peripheral and driver.
Mandatory LDD Functions
The eight mandatory LDD functions are the Install, Remove, Hold, Resume, Reset, Units, Open and
Strategy and they are all discussed in the context of the example device driver A4EXIF.LDD below.
A4Exifinstall
IN: No values are passed to the install vector.
OUT: If successful return with carry clear.
If installation unsuccessful, return with the carry flag set and error number in the
AL register.
PRESERVE: SS, SP and BP
The install vector is called by the operating system when the device driver is loaded in order to
initialise any internal variables. It should not be called directly by an application process but invoked
indirectly by a 'p_loadldd("A4EXIF.LDD")' call. Typically at this stage the various open channel
flags would be initialised to zero but in the case of the A4EXIF.LDD, this has already been done in
the appropriate A4ExifStatusEnt struc headers. As a result, the install vector merely clears the carry
flag and returns.
A4ExifRemove
IN: No values are passed to the remove vector
OUT: If successful return with carry clear.
If installation unsuccessful, return with carry set and error number in the AL
register.
PRESERVE: SS, SP and BP
The remove vector is called by the operating system whenever the device driver is requested to be
unloaded which is usually indirectly as the result of a call to 'p_devdel ("LED", E_LDD)'. ROM-
resident drivers cannot be deleted so any attempt to invoke this vector on them will result in an error
being returned. The code for the remove vector checks to see that all the device driver channels are
closed and returns carry clear if this is the case. In the case of A4EXIF.LDD, a closed channel will
hold a zero in its corresponding StatusEnt open channel flag. If any of the open channel flags is non-
zero then the carry flag is set before returning indicating that an attempt has been made to unload a
device driver that still holds at least one open channel. In the case of A4EXIF.LDD, the
numberofchannels flag is used as a loop counter for the different hardware channel possibilities in a
similar manner to the corresponding code in the open vector.
A4ExifHold
IN: AH register holds one of the following values:
DevHoldNormal, DevHoldPowerDown Or DevHoldPowerFail
OUT: None
PRESERVE: SS, SP and BP
The hold vector is called by the operating system whenever the device driver is requested to be held.
This can occur as a result of three conditions which result in the three different possibilities for the
value held in AH:
1. Device memory segments about to be moved. AH holds DevHoldNormal.
Revision 1.00 Page 66 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
2. Machine about to switch off due to power-save time-out or the off switch being pressed. AH holds
DevHoldPowerDown.
3. Machine about to switch off due to power source being removed or the batteries failing. AH holds
DevHoldPowerFail.
The hold vector code must be able to conduct a rapid shut down of the device driver because in the
case of DevHoldPowerFail, the driver may only have a couple of ms before internal voltages fall to an
unworkable level. The EPOC OS automatically handles the three cases highlighted above but in
Series 3a machines and the Workabout, in addition to these there is another situation that requires the
invocation of the hold vector, namely the opening/closing of the SSD pack doors on an S3a or
Workabout. This is an action which can only be detected by means of software polling which requires
the setting up of the ROM-resident "TcK:" device driver so that the door status can be checked each
system tick (i.e. 32 times a second). The section on A4ExifTickInt provides a more detailed outline of
the TCK interrupt code required to handle pack door opening and closing. It is this latter routine that
polls for the open or closed status of the host machine doors, setting the global HoldFlag accordingly.
The Hold vector code thus includes a check on the status of the HoldFlag and is generally optimised
to be as efficient as possible. An outline of the structure of A4ExifHold presented below. It follows
the pattern for a typical device driver:
e Check the state of the global HoldFlag.
e If the flag is non-zero, then the driver is already held and the function returns without taking
any further action.
e = If the HoldFlag is zero, then the function checks the status of all the channels that the driver
is permitted to open. If any of these channels have their open channel flags cleared, it is not
necessary to do anything as part of the process of holding the channel. Only in the case when
the flags are set is the 'stopChannelRunning function invoked. As with the similar loop in
the Reset vector, the global numberofchannels is used as the loop counter as each of the
possible channels has to be checked.
A4ExifResume
IN: None
OUT: None
PRESERVE: SS, SP and BP
The resume vector is called by the operating system to restart a held device driver. Resume will be
called after a hold caused by any of the four possibilities indicated above in the section on A4ExifHold
but it should be noted that in some cases, ASIC4 will only be switched on after the call to resume.
The device driver is expected to recover from the previous hold and resume any suspended I/O except
in the case of power failure where the resume vector ought to power up the peripheral and put it into a
known state indicating to the user that data may have been lost. The resume vector will also have to
handle the reinstallation of any interrupt service routines by checking the status of the open channel
flag.
e Check the state of the global HoldFlag.
e If the flag is zero, then the driver has already resumed so return without further action.
e If the flag is non-zero, then check the door status of the host machine with a call to the OS
HwGetSsdData service. If the doors are open, then set HoldFlag to 2 to signal this position
to the driver. If the doors are closed, then numberofchannels is used as a loop counter while
the open channel flags of each of the permissible channels for the host hardware are checked.
Only if these flags are set is the 'start TheChannelRunning function invoked.
A4ExifReset
IN: BX holds the device driver device handle
CX holds user specified channel identification data. In this case, holds the address
of the status struc identifying the open channel to be reset.
OUT: None
Revision 1.00 Page 67 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
PRESERVE: SS, SP and BP
The reset vector enables a device driver to reset itself when the application which owns the device
driver terminates abnormally before closing one or more open channels on that driver. The vector is
only invoked by the operating system if it has been primed by means of a call to the ToRequestReset
operating system service in the open vector. Such a call must be balanced by a corresponding call to
IoRequestResetCancel in the close function code of the strategy vector. Registers BX and CX are
required to be set up by the user prior to invocation of either of these services. BX should contain the
device driver handle which is passed through DX in the open vector. CX should hold any suitable
open channel identification data that can be accessed in the driver's internal data space (i.e. through
CS:DI). In the case of A4EXIF.LDD, this information is the address of the channel StatusEnt
structure. If a device driver is only capable of opening one channel, then it is irrelevant what CX
holds. A reset should only be outstanding while some process has a channel open on the device
driver. The format of A4ExifReset is similar to that of a typical reset vector and can be summarised
as follows:
e Move the address of the channel status Ent from CX into DI.
e Check the value of the corresponding cs:[di].A4ExifChannelOpen flag.
e If channel is not open to reset, then return from the vector otherwise call
"StopTheChannelRunning and use HwFreeChannel to release the SIBO serial channel. Set
the ChannelOpen flag to zero.
A4ExifUnits
IN: None
OUT: AX holds the number of channels supported.
PRESERVE: SS, SP and BP
The A4ExifUnits function is called by the operating system when the device driver is requested to
report the number of units (or channels) that it can support. This is primarily useful for purposes of
information.
A4ExifOpen
IN: DX contains the device handle of the device driver
SL is a pointer to an OpenEnt struc
BP is a pointer to an IntEnt struc
DS, ES point to the application process's data segment
OUT: If successful return with carry clear and the address of the open channel in BX.
i.e. BX holds the address of an A4ExifEnt struc which contains various fields of
information concerning the open channel.
If installation unsuccessful, return with carry set and error number in the AL
register.
PRESERVE: DS, ES, SS, SP, BP and DX
The open vector is called by the operating system when a channel to the device driver is required to be
opened. The device handle, which is passed through DX, is used by the operating system to route any
I/O requests on the opened channel to the correct device driver. An LDD must place this handle in
the ChanLibHandle field of the ChanEnt struc of the open channel structure allocated within the
application's data segment. In the case of A4EXIF.LDD, this structure is the A4ExifEnt struc
described in the Appendix to this document. The open vector of a device driver runs in the context of
the process that has called p_open to open a serial port on that device driver.
The OpenEnt struc consists of three fields , OpenNamePtr, OpenMode and OpenChan. The
OpenNamefPtr points to the character immediately following the device name as passed in the
p_open call. For instance, in the case of A4EXIF.LDD, the OpenNamePtr would point to the colon
after LED in the name "LED:". The OpenMode field contains the mode for opening the device driver
Revision 1.00 Page 68 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
which is not used in this example. The OpenChan field holds the I/O channel handle of the device
that the driver is required to 'attach' to. Attached drivers add functionality to, or replace, a service
provided by an underlying device driver. The IntEnt struc pointed to by BP can be used to reload the
various segment registers if their contents have been altered. The A4ExifEnt struc requires further
elaboration. It consists of four fields: A4Exiflo, A4ExifHandlerPtr, A4ExifStatusPtr and
A4ExifA1Ptr. A4ExifHandlerPtr contains a handle to the driver's WaitHandler, A4ExifHandler.
This is the routine required to handle the completion of asynchronous I/O requests and is described in
more detail later on in this chapter. Of the remaining fields, A4ExifStatusPtr holds the location of the
completion status word for I/O requests and A4ExifA1Ptr is a user-defined parameter. These two
values are passed to the strategy vector through the RqEnt structure. A4Exiflo is itself a ChanEnt
struc with sub fields ChanSignature, ChanNext and ChanLibHandle. After initialisation of this
structure, [bx]. A4Exiflo.ChanSignature must hold 'TochanSignature and
[bx].A4Exiflo.ChanLibHandle holds the handle to the device driver (stored in DX). Both of these
values are again required by the strategy vector. The [bx].A4Exiflo.ChanNext field is used by
attached drivers and is set to 0 for root drivers like A4EXIF.LDD.
The code in an open vector follows a similar pattern in many LDDs and is presented in outline form
below:
e Determine the channel to be opened using the pointer to the device name held in
[si]. OpenNamePtr.
e If OK, disable interrupts and invoke the OS HwGet Channel call.
e If OK, then set A4ExifChannelOpen flag to non-zero.
e In order to poll for door-opening and closing, it is necessary to open a "TcK:" channel at this
stage and initialise it by means of using the OS IowithWait service to call the TickInt vector
on each system tick.
e Re-enable interrupts and set up the calling process id using the ProcId service.
e Check for the presence of the required hardware. If present return with carry clear.
e Allocate space in calling process' heap (i.e. the application data space) to contain the I/O
channel control block (an A4ExifEnt struc in the case of A4AEXIF.LDD) and set its base
address to BX (thus BX holds the address of the open channel control block).
e If OK, install the device driver Wait Handler using the IoAddHandler system service. A
Wait Handler is required only if there are any asynchronous I/O requests to be handled.
e If OK, initialise the fields inside the I/O channel control block that were outlined above.
e Invoke IoRequestReset system service to handle unexpected termination of main program
by invoking the driver's Reset vector.
e Before leaving the Open vector, if the call succeeded, BX must hold the open channel control
block handle.
A4ExifStrategy
IN: BX holds the allocated channel control block initialised in the open vector
DX contains device handle of the device driver in the case of an LDD
SL is pointer to RqEnt struc
BP is pointer to IntEnt struc
DS, ES point to data segment of application making the I/O function request
OUT: If successful return with carry clear. Furthermore, in this case, if the strategy
vector is meant to complete the I/O request (as is the case with IoClose for
instance) then the completion status should be written back to RqStatusPtr location
and the I/O semaphore signalled by calling IoSignal. If the I/O request is not completed
by the strategy vector (as is the case with the asynchronous functions IoFuncRead
and IoFuncWrite) then PendingErr should be written back to the location pointed to by
RqStatusPtr and the I/O semaphore should not be signalled.
If installation unsuccessful, return with carry set and error number in the AL
register.
PRESERVE: DS, ES, SS, SP and BP
Revision 1.00 Page 69 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
When an application makes a I/O request on the opened device driver channel, the request is routed
to this vector by the operating system. A device driver defines the set of strategy functions that it
supports such as IoFuncSet, IoFuncSense, IoFuncWrite and IoFuncClose. The functions of a
device driver are usually dependent on its purpose and there is no requirement to support any
particular function. The ordering of these functions in the strategy vector table is defined in p_file.h
and presented in A4EXIF.ASM.
The SI register contains a pointer to an RqEnt struc which consists of four fields: RqFunction,
RqStatusPtr, RgA1Ptr and RqA2Ptr. RqFunction contains the function number passed to the I/O
request by the application. In the device driver strategy vector code, the value held in RqFunction is
compared against the supported function numbers held in ToFuncClose, IoFuncRead etc. If the
function number is not one of those supported then a call to IoRoot is necessary in the case of a root
device driver such as A4EXIF.LDD. toRoot chains the I/O request through to the operating system
which runs some default code to handle it. RqStatusPtr is a pointer to a memory location in the
application data space which holds the value of the I/O request's completion status word. While a
request is outstanding, this value is set to PendingErr and only when it completes does a completion
code get written to this location. I/O requests can complete within the strategy vector or later after an
interrupt. Often as is the case with A4EXIF.LDD, only a single request of any one kind can be
outstanding at any time otherwise the application is panicked. RqA1Ptr and RqA2Ptr hold the values
of two parameters that are passed to the IoAsynchronous EPOC service. Each synchronous strategy
function has a similar pattern with explicit I/O being conducted whilst interrupts are disabled and a
completed request being signalled with an OS ToSignal call prior to exit from the function. This call
signals to the OS the completion of the particular I/O request entailed by the function call. The
situation with regard to the one asynchronous strategy function is somewhat more complicated and is
dealt with in greater detail in a later section.
The structure of the strategy vector of A4EXIF.ASM is outlined below:
e Determine the strategy function number using [si].RqFunction and compare with the below:
e JIOFUNCREAD: Asynchronous read of latches U4 and U3. Panic if [bx].A4ExifStatusPtr !=
0. Update [bx].A4ExifA1Ptr and [bx].A4ExifStatusPtr with [si].RqA1Ptr and
[si].RqStatusPtr respectively as the locations to be accessed on receipt of interrupt. Move
PendingErr into the location pointed to by [bx].A4ExifStatusPtr to signal that the request is
awaiting completion. Allow handler to be enabled through the IoEnableHandler OS call
and exit without signalling completion of the request.
e IOFUNCWRITE: Identical behaviour to that of IoFUNCSET which it calls.
e TIOFUNCCANCEL: Used to cancel any pending asynchronous reads. This involves
disabling the wait handler, consuming any stray signal from the interrupt routine by means of
an OS IoWaitForSignal call and then storing cancelErr in the channel I/O request status
word.
e IOFUNCCLOSE: Close down the TCK channel and remove handler. Disable interrupts
and HwFreeChannel setting A4ExifPid to 0 before re-enabling interrupts. Invoke
IoRequestResetCancel system service and HeapFreeCell. Signal completion of I/O
request by calling IoSignal system service.
e IOFUNCSENSE: Reads the status and LED bytes from latches U4 and U3 respectively
storing the results at the addresses pointed to by RgA1Ptr and RqA2Ptr.
e IOFUNCSET: Sets latch U5 to contain the value pointed to by the sole argument in the
call to P_FSENSE.
e If not supported then call IoRoot system service.
The Non-Mandatory LDD Functions
The eight functions described above must be supported by all device driver. Typical Psion LDDs
employ at least two other LDD functions. The first of these is a pseudo-interrupt routine which is
invoked by the OS on each system tick. In A4EXIF.LDD, this function is represented by
A4ExifTickInt and an outline of its purpose was presented earlier in the discussion on holding and
Revision 1.00 Page 70 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
resuming device drivers. As was indicated then, the minimum functionality required by this routine
is to poll the status of the host machine doors and if appropriate call the driver's Hold and Resume
vectors. If in addition the LDD is intended to service any asynchronous I/O requests, a wait handler
and common interrupt service routine are required. With A4EXIF.LDD, these two additional
functions are represented by A4ExifHandler and ComInt respectively. The former function
constitutes the second of the additional LDD functions as can be seen by examining the LibEnt
structure for A4EXIF.LDD. The latter function is set up so that it replaces the default interrupt
service routine code invoked by the OS on the receipt of hardware interrupts on the peripheral's SIBO
channels. A4ExifHandler is invoked by the OS every time the I/O semaphore of the process that
opened the channel is signalled with through an IoSignalByPidNoResched call indicating that an
interrupt has been received and an outstanding I/O request has completed. The function of the wait
handler is to deal with I/O semaphore signalling and to update the appropriate open channel control
block field variables. The common interrupt service routine code in ComInt cannot do this because it
is not permitted to access the application data space. This in turn is because the routine runs in the
context of the process which was running when the interrupt occurred. A4ExifTickInt, the wait
handler and the common interrupt service routine for A4EXIF.LDD as well further details as to how
the latter two interact to handle asynchronous I/O requests are described below.
A4ExifTicklint
As was explained earlier in discussing the A4ExifHold vector, it is necessary to utilise the "TcK:"
system tick device driver in order to handle the particular case of invoking a hold on A4EXIF.LDD
when the host machine SSD pack doors are opened. Such an action automatically causes power to be
removed from any peripherals. The TCK driver is opened via an OS Toopen call in the A4ExifOpen
vector which returns with carry clear and a non-zero handle in AX if successful. In this case, the
IoWithWait function is called to request an synchronous I/O service from the TCK driver. Prior to
this call, the service number requested is held in AL and the I/O handle procured from the previous
call to ToOpen is loaded into BX. The interrupt number of the tick poll routine, A4ExifTickInt, is
loaded into CX so that as its parent driver is invoked on each system tick, the OS enters this vector.
The reason the TickInt routine is required in A4EXIF.LDD is solely to handle the problem of
recognising a sudden removal of power from the host machine. The OS has no way of testing for this
condition other than polling its global 'Doorstatus' variable every system tick and taking the
requisite course of action. As such, the outline of the code for the tick poll routine which is required
in all Psion LDDs can be presented below. This outline should be carefully compared with the
structure of the Hold and Resume vectors shown earlier in order to see how they interact:
e Check the current status of doors which is held in SI.
e¢ If DoorlsOpen then if global HoldFlag is zero, force a call to A4ExifHold, set HoldFlag to 2
and return far
else do a far ret
e = Else if DoorIsClosed then
if global HoldFlag is 2, force a call to A4ExifResume and return far
else do a far ret
It should be emphasised that A4ExifTickInt is only a pseudo interrupt service routine in that it does
not preserve the status of the registers which is something that the device driver writer must
undertake to ensure is done explicitly.
The handling of synchronous and asynchronous I/O
The provision of synchronous and asynchronous I/O services are an important aspect of writing any
device driver. In the case of Psion drivers, all such services are the provided through the Strategy
vector which is typically preceded by a Strategy Vector Table listing the complete set of I/O services
that can be invoked on the driver. The strategy vector table for A4EXIF.LDD is presented below to
provide an indication as to the kind of service routines that can be written:
StrategyVectorTable label word
Revision 1.00 Page 71 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
dw offset A4ExifDefault 7StrategyPanic
dw offset A4ExifRead ;StrategyRead (function define is P_FREAD)
dw offset A4ExifWrite ;StrategyWrite (function define is P_FWRITE)
dw offset A4ExifClose ;StrategyClose (function define is P_FCLOSE)
dw offset A4ExifCancel ;StrategyCancel (function define is P_FCANCEL)
dw offset A4ExifDefault 7StrategyAttach
dw offset A4ExifDefault 7 StrategyDetach
dw offset A4ExifSet ;StrategySet (function define is P_FSET)
dw offset A4ExifSense ;StrategySense (function define is P_FSENSE)
Both synchronous and asynchronous I/O requests can be made on the driver through means of the
PLIB 'p_iow (pcb, <func>, &A1, &A2)' call where pcb is the open channel handle, <func> is one of
the above function defines and Al and A2 are two optional parameters required for the servicing of
the request. The routing of an I/O request to the correct service code is done by the common code at
the head of the strategy vector. Each time this vector is entered, BX holds the address of the open
channel control block, DX the device handle of the device driver and SI a pointer to the strategy
RqEnt struc used by the OS to follow the course of the I/O request. Using this information, it is
possible to access all the relevant flags in the channel StatusEnt by moving [bx].A4ExifStatusEntPtr
into DI. This leaves us with the open channel control block in DS:BX and the channel StatusEnt in
CS:DI.
Armed with the above information, it is possible to outline the general pattern of both synchronous
and asynchronous I/O requests at an OS level. The case of synchronous requests is particularly
straightforward since the servicing of the request can be completed entirely within the relevant
strategy vector table function. It should be emphasised that in the outline presented below, disabling
and re-enabling of interrupts only actually has to be done around any I/O.
SYNCHRONOUS I/O REQUEST STRATEGY VECTOR TABLE FUNCTION
pushf
cli ;Disable interrupts
< request service code > ;Relevant synchr. I/O processing
ExitWithCompletionStatusZero:
< set I/O request status word to zero >
IoSignal ;Signals completion of I/O to OS
XOr ax, ax
onl ol ;Tells OS that strategy exited OK
popf ;Re-enable interrupts
ret
ProcEnd noret
Note that in the above outline, the single ToSignal call is made after completion of the I/O request in
order to signal this fact to the OS. The situation is somewhat more complicated in the case of an
asynchronous request because the I/O request strategy vector table function has to interact with both a
wait handler function and an interrupt service routine. Of the I/O request services outlined above for
A4EXIF.LDD, only one, namely A4ExifRead, is asynchronous and it serves as a good illustration of
the nature of programming for asynchroneity. The steps taken in the A4ExifRead vector are outlined
below:
e = Set the ChannelReadCompleted flag to 0 (stored in cs:[di]. A4ExifChanReadCompleted)
e If the address of the I/O request status word is non-zero then panic (i.e. there is an
outstanding read request)
e Update the open channel control block variables using the RqEnt struc
e Load I/O request status word with PendingErr
e Enable the wait handler by using the To—EnableHandler OS service
The read request is now in a pending state waiting for completion via receipt of a hardware interrupt.
When such an interrupt is received, the OS switches into the appropriately configured common
interrupt routine ComInt. Here, the channelReadCompleted flag is set to indicate to the handler that
the read request has completed. An IoSignalByPidNoReSched OS service call is also made to
indicate to the OS that an as yet unspecified I/O request has terminated. This signal is consumed by
the OS which means that at this stage, an IoSignal for completion of the original asynchronous
request has yet to be made. The interrupt service routine exits after sensing the status and LED byte
values from the ASIC4 Example Interface Board and loading the appropriate response bytes into the
relevant locations in the device driver code segment. More details as to the functionality of the
interrupt service routine are provided in the section on interrupts. The OS now invokes all the
currently active wait handlers in order to determine which application is responsible for consuming
Revision 1.00 Page 72 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
the completed read. The wait handler code includes the all-important IoSignal call that indicates to
the OS that the original asynchronous read request has finally been accounted for. Receipt of this
signal by the OS constitutes completion of the request. The outline code for the A4EXIF.LDD wait
handler A4ExifHandler is outlined in the next section.
A4ExifHandler
A WaitHandler is a special function of the LDD which is nominated to be called by the operating
system every time the I/O semaphore of the process that opened the channel is signalled. It will only
actually be called if the application is already waiting for an outstanding I/O request to complete (1.e.
while the application is hung in p_iowait). The handler function is the means by which hardware
interrupts can be filtered through to the process which opened the I/O channel since it permits the
rescheduling of processes.
The WaitHandler is invoked in the open vector by using the IoAddHandler system service. When an
application makes an I/O request, the I/O semaphore is signalled and the operating system calls the
Wait Handler function while the application is waiting for the request to complete. The wait handler
returns with CLC if no outstanding request has completed. Otherwise the wait handler returns with
STC and zero in AL. The wait handler can include within it synchronous I/O requests to cancel or
use up signals but it is not entered recursively (i.e. re-enterently) by the operating system. A wait
handler is best viewed as a necessary requirement in dealing with the I/O semaphore signalling which
cannot entirely be addressed in the appropriate interrupt service routine because the latter is not able
to access the open channel's control block.
Interrupts and Interrupt Service Routines
The SIBO architecture allows for eight separate hardware interrupt sources. The EPOC operating
system provides a GenSetRevector service to enable a device driver to install an interrupt service
routine for any of these eight interrupt sources. When an interrupt occurs, the operating system
preserves the state of all the registers before calling the appropriately-installed interrupt service
routine. As a result of this, the interrupt service routine is free to employ any register it sees fit to use.
A few important points ought to be made concerning the code within an interrupt service routine:
e On an 8086 processor, interrupts cannot be nested so their is no requirement to disable
interrupts whilst inside the interrupt service routine.
e Interrupt service routines should operate as fast as possible. In general, operating system
service routines are tuned to be of less than Ims duration.
e Interrupt service routines run in the context of the process that was running at the time of the
interrupt and should access only the device driver data space which, as with A4EXIF.LDD,
typically resides in its own CS space.
e Interrupt service routines should not cause a process rescheduling. To indicate that an event
has occurred to the interrupted process, the ToSignalByPidNoResched system service
should be called. If a call is made to this service, the interrupt service routine should exit
with CLC otherwise it returns with STC.
The interrupt routines called require knowledge as to the particular hardware SIBO channel being
used by the driver at the time an interrupt occurs. This information is passed through to the
GenSetRevector function in StartInterrupts by loading the address of the appropriate Int Vec routine
from the A4ExifChannelIntVec field of the channel StatusEnt struc. As a result, when an interrupt
occurs, the currently loaded IntVec routine is invoked. All the Intvec routines reload DI with the
appropriate address of the channel StatusEnt in the device driver code segment before falling through
to the common interrupt routine service code held in ComInt.
Comint
Revision 1.00 Page 73 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
The common interrupt service routine code resides in the ComInt vector. The structure of this code is
presented below. It should be emphasised that no data in the application data space and hence in the
open channel control block can be accessed from ComInt. This explains why it is necessary for the
OS to invoke a wait handler to clean up after the interrupt service routine code for a particular
asynchronous I/O request has been run.
e Check the value held in the chanReadCompleted flag
e If this value is 2 then we do not have an asynchronous read completed but rather the
interrupt line has been pulled low outside of an asynchronous I/O request.
e If this value is 1 then we have an asynchronous I/O request completed and so
IoSignalByPidNoResched must be invoked to signal to the OS that a read has completed.
e In both cases, sense the status and LED bytes from the Example Interface hardware and load
these values in the device driver's code segment A4ExifStatusEnt struc.
e There are four possibilities of status byte corresponding to the four combinations offered by
the two input switches, S1 and S2. These are used to output one of four separate LED bytes
to the LEDs.
e Awrite to AlNonSpecificEoi register (or A9BNonSpecificEoiW in the case of an ASIC9
machine) must be done prior to exiting to let the OS know that the installed interrupt service
routine has terminated.
Other important local device driver functions
The functions presented in this section are local to A4EXIF.LDD and perform various important tasks
relating to the peripheral hardware such as groping the hardware and setting interrupts running.
Since these tasks have to be undertaken by most device drivers, the relevant functions are outlined in
greater detail.
A4ExifCheckHardwarePresent
Every Psion device driver has a characteristic 'CheckHardwarePresent or 'GropeHardware" function
that usually involves checking for the presence of the required peripheral device by means of
comparing a couple of ASIC4 identification bytes returned by the peripheral in response to a SIBO
serial protocol identification message with the expected answers. The specific value of the InfoByte is
unimportant as long asa "test al, al" call is made which will always return a non-zero answer if
ASIC4 is present. In that case, the extended info byte should be tested for against what is expected
from address lines A23-A27.
Psion Workabout/HC machines have three physical serial links and two of these are accessed via the
SSD slots. The third link corresponds to the serial expansion port. In order for a driver to talk to a
peripheral connected to this port, it must specifically select this serial link. In order to prevent
multiple access to a single peripheral, it is necessary in the first instance to check whether the serial
channel is free or not. A call to the operating system function HwGet Channel with the appropriate
interrupt mask in AL returns with CLC if the channel was captured successfully. Logically this call
should be made in the Open vector but since it can only sensibly be made after the hardware has been
successfully located it can be placed at the end of the GropeHardware function. A corresponding call
to HwFreeChannel must be made when closing the channel. To actually select a channel prior to
communication along it, a call to HwSelectChannel Is necessary.
A4ExifStartChannelRunning
This function is called at the end of the Open vector to set the ASIC4 Example Interface hardware
running. It can also be invoked by the Hold vector. The function first checks the status of the global
StatusEnt ChannelRunning flag. If this flag is clear, CheckHardware is called to determine whether
the hardware is still connected and then StartInterrupts is called before the channelRunning flag is
Revision 1.00 Page 74 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
set to indicate that the channel hardware has been started. The function returns with CLC on
successful completion or with STC if no hardware was located.
A4ExifStopChannelRunning
This function simply clears the channelRunning flag if set and calls StopInterrupts unless the
channel already has its ChannelRunning flag clear. The StopChannelRunning function will be called
by Strategy vector when trying to close a channel and can also be called by the Resume vector.
A4ExifStartinterrupts
StartInterrupts is called whenever a call is made to StartChannelRunning. At the heart of the
function is a call to the OS GenSetRevector function which is used to install a specified interrupt
service routine in the place of the default routine held in the interrupt vector table. GenSetRevector
is called with the interrupt vector number of the service to be replaced in AX and the offset and code
segment of the replacement interrupt vector service in BX and CX respectively. BX is loaded from
the ChannelIntVec field of the channel StatusEnt which holds the name of the specific interrupt
service routine code (i.e. IntVecO, IntVec1 etc.). The latter functions set up the appropriate channel-
specific variables before falling through to the common ComInt routine. The channel interrupt mask
which is machine and channel dependent is written to the appropriate register on the host ASIC. In
the case of ASIC9, this register will be A9BInterruptMaskRW. For ASIC1 it will be
AlInterruptMask.
A4ExifStopInterrupts
StopInterrupts reinstalls the original interrupt service routine by invoking the GenResetRevector OS
system service and signalling the interrupt mask to the corresponding host ASIC register.
Structures and Include files
Epocdef.inc and device driver strucs
Epocdef.inc is an important header file that contains the definitions of various strucs extensively used
in the construction of device drivers. It also contains the definitions of all the OS error values such as
DeviceErr and NameErr that are used in A4EXIF.LDD to communicate an error to the application
via AX. Listed below and overleaf are the key strucs defined in Epocdef.inc that were used in the
coding of A4EXIF.LDD.
LibEnt struc Start of device driver
LibSignature dw ?
LibInfo dw 2
LibCount dw ?
LibBase dw ?
LibEnt ends
OpenEnt struc Pointed to by SI in Open vector
OpenNamePtr dw ?
OpenMode dw ?
OpenChan dw ?
OpenEnt ends
ChanEnt struc Used in open channel control block
ChanSignature dw 2
ChanNext dw ?
ChanLibHandle dw ?
ChanEnt ends
IntEnt struc Pointed to by BP in Open and Strategy vectors
IntFrame dw ?
IntBP dw ?
IntES dw 2
IntDS dw ?
Revision 1.00 Page 75 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
IntPC dw ?
IntCs dw 2
IntFLAGS dw ?
IntEnt struc ends
RqEnt struc Pointed to by SI in strategy vector
RqFunction dw 2
RqA1Ptr dw ?
RqA2Ptr dw ?
RqStatusPtr dw ?
RqEnt struc ends
A4EXIF channel strucs
These are defined at the start of the A4EXIF.LDD code segment. The open channel control block is
held in a structure of type A4ExifEnt and is allocated space from the heap of the process invoking the
device driver's open vector. As such, it cannot be accessed from the Hold, Resume and Reset vectors
or from the interrupt service routine, ComInt. The channel StatusEnt holds various key channel
related flags. Each hardware channel has its own StatusEnt which is instantiated in a header in the
device driver code segment following the LibEnt structure. This header block is usually held in
CS:DI which is how the StatusEnt variables are accessed. The structure of both A4EXIF channel
strucs is shown below:
A4ExifEnt struc OPEN CHANNEL CONTROL BLOCK
A4xifIo ChanEnt<>
A4ExifHandlerPtr dw ? Pointer to the Wait Handler
A4ExifStatus dw ? Address of I/O request status word
A4ExifAlPtr dw ? Pointer to first argument
A4ExifA2Ptr dw 2. Pointer to second argument
A4ExifStatusEntPtr dw ? Pointer to channel's StatusEnt
A4ExifTickHandle dw ? Handle to the TCK device channel
A4ExifEnt ends
A4ExifStatusEnt struc CHANNEL STATUS_ENT
A4ExifChannelPid db ? Process id of process holding
channel open
A4ExifChannelOpen db 2 Is the channel open or not?
A4ExifChannelRunning db ? Is the channel running?
A4ExifChanReadCompleted db ? Flag used to indicate to handler
when
A4ExifChanneliIntMask db ? Contains the HW channel interrupt mask
A4ExifChannelIntNum db ? Holds no. of interrupt vector to be
replaced
A4ExifChannelSelect db 2 SIBO channel select flag
A4ExifChannelDummy db 2 Spare
A4ExifChanneliIntVec dw ? Holds replacement int. vector routine
name
A4ExifStatusEnt ends
Ossibo.inc and Ospack.inc
Ossibo.inc is an important header file that contains the defines for all the ASIC2 and ASIC9 register
addresses. Ospack.inc contains similar information but for ASIC4.
Revision 1.00 Page 76 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
12. AN EXAMPLE DEVICE DRIVER FOR ASIC5:
SYS$AS5.PDD
Introduction
In this chapter, the functionality and code structure an example installable physical device driver,
SYS$AS5.PDD, is presented in some depth. Circuit details of the corresponding Psion peripheral for
this driver, the Psion 3-link, were outlined in chapter 8. SYS$AS5.PDD enables software written
using the Psion SDK to communicate with the 3-link peripheral through means of standard PLIB
calls such as p_open' and 'p_write'. This peripheral incorporates an ASICS as the SIBO serial
protocol slave device. As explained earlier in chapter 7, ASICS has an on-board 16550 UART which
means that it can be used in conjunction with the standard serial LDD provided an appropriate PDD
is loaded. SYS$AS5 is a PDD intended for this purpose and its description in this chapter provides a
clear insight into the generalised structure and construction of physical device drivers for peripherals
based around the SIBO architecture.
The LDD-PDD interface
All Psion device drivers have a LibEnt structure at the head of their code segment which includes a
vector table defining the functionality of the driver. In the case of SYS$AS5, four vectors are defined.
These are: Install, Remove, Open and Strategy. The structure of the first three of these are fixed for
most device drivers but the fourth can be specified in any way. This fourth vector defines the LDD-
PDD interface and is constructed to allow the two drivers to best communicate with each other. In the
case of serial PDDs, the approach taken is modelled on the LDD strategy vector with the
corresponding strategy vector table and function numbers. This is a logical choice but it is important
to emphasise that the LDD-PDD interface is completely user-definable and that the approach
described in this chapter is optional.
The key feature of any LDD-PDD interface is that the LDD must have no explicit concept of
hardware. In the case of the serial LDD, for instance, it knows that it has a serial port that it can read
data bytes from or write data bytes to but it is ignorant of the explicit implementation of the hardware
at this port. That aspect is handled by the corresponding PDD which handles all the specifics of data
byte I/O. In the case of an application writing a buffer to the serial port by means of a
p_iow(P_FWRITE....) call, for instance, the LDD will first copy the data in the application's DS into
a local CS buffer. It will then call the PDD to indicate that it intends to start sending data bytes when
the PDD is ready to start receiving. When the PDD is ready to commence sending a byte out of the
serial port, it calls a function (TransmitByte) in the LDD. This function reads the next byte to be
transmitted from its local buffer and hands it to the PDD. The PDD duly transmits the byte and again
calls TransmitByte until all the bytes are completed. The LDD then sends a special 'NothingToSend'
signal to the PDD which indicates that transmission is finished. The LDD also sends an
IoSignalByPidNoResched which causes its wait handler to be invoked by the OS. In this way, the
IoSignal that signifies completion of the original write request is invoked by the LDD. Note that the
LDD has no concept of interrupts, merely of sending a byte at a time and registering completion or
otherwise of I/O requests. Futhermore, the PDD never takes the initiative from the LDD and merely
undertakes one function at a time before returning control back to the LDD. The LDD-PDD interface
is examined in greater depth later in this chapter when the structure of the PDD strategy vector is
presented.
Revision 1.00 Page 77 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Code Structure
Device Names and Loading SYS$AS5.PDD
SYS$AS5.PDD is loaded into the RAM of the host machine by means of the following PLIB call in
the application code:
p_loadldd("SYSS$AS5.PDD") ;
The name of a device driver is the mechanism by which an application can obtain a channel to that
device driver. LDDs all have three character names followed by a period, a further three characters
and acolon. The first three characters of a PDD name are the name of the LDD to which the PDD
belongs. The second set of three characters uniquely identify the PDD. The device name is required
to uniquely identify the LDD to the OS when attempting to open a channel on it. The SYS$AS5 PDD
belongs to the "TTY:" LDD. Its name as defined in its LibEnt structure is 'TTY.SR5'. Thus a
channel with its handle in pcb may be obtained on it at the application level by means of the
following call:
p_open (&pcb, "TTY.SR5:A",-1);
The qualifier after the colon indicates that the driver can support more than one channel. Channels
are allocated a single character sequentially from the character 'A' up to the character 'C'. The
number of channels that can be supported in this way is dependent upon the host hardware. Only one
expansion port can be opened on the S3a for instance whereas three are possible on the Workabout
and HC. EPOC uses the driver name in the p_open call to invoke the ToOpen system service which in
turn invokes the Open vector on the associated device driver.
The Single Code Segment and Data Storage
All data associated with a physical device driver must be stored in its code segment. Examples of
such data are the channel interrupt masks and numbers that have to be visible to all processes that
may be using SYS$AS5.PDD.
The overall structure of the code segment is typical of Psion physical device drivers. The segment
begins with a CodeSeg directive followed by the LibEnt structure which defines all the device driver
functions. Before entering the code for these functions, all global variables are declared in the
internal (CS) data space. Following the code for the LibEnt functions comes the code for all the local
driver functions, After these are the EndCodeSeg and end OsAs5PDD directives.
The Channel struct and A5Ent struct
At the head of the driver's assembler source file, SYS$AS5.ASM, various constants, compiler defines
and types are listed. It is here that templates are declared for the global structures that hold the key
driver variables. in the case of SYS$AS5, one main structure, the Sr5ChannelStruct, is employed to
hold the various important flags and masks that relate to the status of each separate channel on the
driver. This structure is termed the Channel struct and its fields are filled in during the course of
running the PDD install and open vectors. Whenever the serial LDD invokes one of the PDD
functions, the application must ensure that CS holds the address of the PDD's code segment which is
where the Channel struc resides. The channel's Channel struct is usually accessed through DI or BX
depending on preference. Its layout is presented later in this chapter along with other important
defines that were used in the construction of SYS$AS5.PDD.
SIBO hardware and conditional compilation
As indicated previously, the number of expansion channels supported by a host Psion machine is
dependent on the hardware. In the case of the S3a, only one SIBO channel can legitimately be
opened corresponding to expansion port A. With the HC and the Workabout, it is possible to open up
to three separate SIBO channels on ports A through to C. SYS$AS5.PDD is constructed to enable it
to run on any host Psion platform. In its internal data space, the various hardware options for the
SIBO channels, interrupt masks and interrupt numbers are coded in a large if statement thereby
Revision 1.00 Page 78 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
permitting conditional compilation of the driver for the required host hardware. The only change that
need be made in adapting it for use on another Psion machine is the alteration of the build flag at the
start of the code segment. This flag indicates to the compiler which SIBO machine flags as well as
other variables should be set. The conditional compilation table outlined here is worthy of some study
because it encapsulates all the information regarding masks and SIBO hardware channels required by
the prospective developer interested in constructing a multi-platform peripheral and accompanying
PDD.
The PDD Functions
OsAS5install
IN: Nothing
OUT: If successful, return with carry clear
If installation unsuccessful, return with the carry flag set and error number in the
AL register
PRESERVE: SS, SP, BP
The install vector is called by the parent LDD whenever the PDD is required to be loaded. It cannot
be called directly be an application only indirectly through the LDD in its Install vector. The install
vector is called in the context of the OS with DS and ES in an unknown state. Memory will not be
moved while in this function so the normal rules governing the use of ES and DS may be ignored.
OsAS5Remove
IN: Nothing
OUT: If successful, return with carry clear
If installation unsuccessful, return with the carry flag set and error number in the
AL register
PRESERVE: SS, SP, BP
The remove vector is called by the parent LDD whenever the PDD is required to be unloaded. It
cannot be called directly by an application and only indirectly through the LDD in its Remove vector.
The remove vector is called in the context of the OS with DS and ES in an unknown state. Memory
will not be moved while in this function so the normal rules governing the use of ES and DS may be
ignored.
OsAS5Open
IN: SS:SI points to the OpenEnt structure
ES, DS point to the DS of the application process.
OUT: If successful, return with carry clear and control block in BX
If installation unsuccessful, return with the carry flag set and error number in the
AL register
PRESERVE: SS, SP, BP
The open vector is called by the parent LDD whenever a channel to the PDD is required to be opened.
It cannot be called directly by an application and is typically invoked in the higher level LDD Open
vector code by means of the DevOpenPpp OS system call. On invoking the open vector, SI points to
the OpenEnt structure which contains three fields, namely OpenNamePtr, OpenMode and OpenChan.
The OpenNamePtr points to the qualifier immediately following the device name in the call to
p_open. In the case of SYS$ASS5, for instance, the OpenNamePtr would point to the 'a' in the name
"TTY.SR5:A". This corresponds to an attempt to open the first hardware SIBO channel on the host
machine which if successful will leave the address of the ChanO Sr5ChannelStruct in BX. The PDD
open vector finally includes a call to the OS service HwGet Channel to obtain the requested SIBO
channel.
Revision 1.00 Page 79 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
The order of action undertaken by the parent serial LDD's open vector is generally fairly complicated
and includes various calls to the PDD strategy vector routines. The situation is outlined overleaf:
e Ensure that the LDD itself can be opened.
e Call the PDD open vector using the OS DevOpenPDD OS call.
e = If successful, call the OS service DevGet PDDAddress which returns the full segment:offset
address of the PDD's fourth strategy vector in BX:AX. These values are loaded into the
dword Channel struct field SerialPDDEntry.
e Invoke the PDD strategy Open and SetHandlerCS functions to set up offsets and segments
respectively to locations in the LDD above.
e Invoke strategy Set to initialise the transmission baud rate.
e Invoke strategy Start to set-up and then enable interrupts
Once the DevGetPDDAddress service has been used to load the LDD's SerialPDDEntry field, it may
be used to load in the address of any of the PDD's strategy functions. The DevGetPDDAddress OS
call invoked in the LDD open vector must also be invoked in the LDD resume vector code since
memory may have been moved while the LDD was held. The PDD is ignorant of such activity since
the serial LDD is responsible for handling all holds and resumes.
OsAS5Strategy
IN: AX holds the vector number
ES, DS point to the DS of the application process.
OUT: If successful, return with carry clear and control block in BX
If installation unsuccessful, return with the carry flag set and error number in the
AL register
PRESERVE: SS, SP, BP
The strategy functions are invoked directly from the various serial LDD vectors to provide hardware-
specific services. For instance, in order to set up the baud rate, it is necessary to invoke strategy Set.
The strategy vector table for OsAS5Strategy is presented below and then the functionality of the
important component vectors is outlined:
AS5StrategyJumpTable label word
dw offset AS5Open ;Load Handler offsets
dw offset AS5Close ;Close the channel
dw offset AS5Start ;Start the channel
dw offset AS5Stop ;Stop the channel
dw offset AS5Set ;Set the channel status
dw offset AS5Sense ,;Return channel status
dw offset AS5Control ;Drive the handshaking lines
dw offset ASS5Enquire ;Returns baud rate
dw offset AS5Enable ;Begin sending output
dw offset ASS5SetHandlercCs ;Load Handler segments
Open and SetHandlerCS go together and are invoked from the LDD open and resume vector code.
Both are required to let the PDD know the address at which its LDD resides. The four full addresses
passed through to Open and SetHandlerCS are of the LDD's control block and the LDD StatusInt,
RecvInt and XmitInt vectors. Close is called in order to close an opened channel. Start and Stop are
used to enable/disable interrupts and are invoked from the LDD open, hold/resume and set vectors.
The order of action in the PDD Start vector is as follows:
e Initialise PDD variables
e Check H/W present
e Start the hardware running. In the case of SYS$ASS5, part of this process involves starting a
continuous clock from the host controller ASIC in order to trigger the UART clock on the 3-
link's ASICS. In addition to this clock, the RTS and DTR lines must be driven low.
e = Start interrupts.
The common interrupt service routine code resides in the PDD ComInt function. This code is patched
into the interrupt vector via the GenSetRevector system service. The interrupt mask contains bits to
Revision 1.00 Page 80 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
generate the following interrupts: Receive character, Ready to send next character and Modem line
change character. In SYS$ASS, all three interrupts are enabled in Start. It is important to realise
that after masking in these bits, a Ready to send next character interrupt is almost immediately
generated so the corresponding ComInt code must be able to handle this.
CheckHardwarePresent
This non-mandatory function is called from the Open vector and follows the lines of previously
discussed CheckHardwarePresent code. After checking for an ASICS at the end of the serial link, the
function returns with the carry flag clear if one is found. If a non-zero info byte is returned with an
Asic5Normalld, then various other IDs are tried (Asic4Id, Asic8Id, Asic5PackId) before returning
with the carry flag set.
CheckHardwarePresentFromStart
This is a non-mandatory function called only from the PDD Start vector. After checking that we have
an ASICS at the end of the SIBO channel, the function sets the S_PERIPHERALMODE bit of the
A5PortBMode register. This then puts ASICS into UART mode.
Comint
The common interrupt routine code is entered with DI holding the address of the appropriate channel
struct. ASICS's control register (A5CtrlReg) is read first to determine which interrupt has occurred.
The byte read from the register is compared against S_ MDINT (Modem lines interrupt), S_RXINT
(Receive character interrupt) and S_TXINT (Transmit interrupt). The code to handle each of these
cases is then entered prior to returning control back to the LDD via the Channel struct fields that were
filled by a previous LDD calls to the PDD strategy Open and SetHandlersCS vectors. The LDD has
no knowledge of interrupts and the purpose of ComInt is therefore to hide the hardware details of
handling interrupts from the LDD. Once the interrupt has been serviced, a write is made to
A9BNonSpecificEoiW in the case of ASIC9 or AlNonSpecificEoi for an ASIC1/ASIC2 based system
to indicate to the OS that the interrupt has been serviced.
Revision 1.00 Page 81 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
13. DEBUGGING AND TESTING DEVICE DRIVERS
Introduction
This chapter will detail the techniques that can be used by the developer to first debug and then test
device drivers. The emphasis will be on the software methods such as:
e¢ Good use of variables. e.g. Starting all the fields in the CS Channel Status structure with
CS.
e Debugging by eye. Even more important with regard to device drivers.
e Using SDBG. The pitfalls and benefits. Working your way around the strategy vector calls
with SDBG.
e Construction of C test harness programs. Catching all the error flags that can be returned by
device driver functions.
e The comprehensive memory check program mem.c.
Debugging Techniques
A Psion device driver is written in 8086 assembler as an asm file and built using the Borland Turbo
Assembler compiler. The subsequent debugging process centres around the construction of an
appropriate PLIB test harness. The purpose of a test harness is to check a number of the device driver
vectors to ensure that they do not return errors or cause panics. The majority of PLIB calls that would
be used in this context return a negative integer that is used to ascertain the cause of the problem in
the corresponding device driver vector. The code below, for instance, would be used to test the install,
open, strategy close and remove vectors of the A4EXIF LDD:
GLDEF_C VOID main(VOID)
{
VOID *serH;
INT ret;
if ((ret=p_loadldd("A4EXIF.LDD") ) <0)
{
p_printf ("Error %d on p_loadldd", ret);
p_getch ()
p_exit (0)
}
else
p_printf ("Successfully loaded A4EXIF.LDD");
if ((ret=p_open(&serH, "LED:",-1) ) <0)
{
p_printf ("Error %d on p_open", ret);
p_getch();
x
else
p_printf ("Successfully opened LED: channel");
p_close(serH) ;
p_printf ("Successfully closed LED: channel");
}
p_devdel ("LED",E_LDD) ;
p_getch();
p_exit (0);
}
Revision 1.00 Page 82 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
If as often happens at this stage, a bug in the device driver causes the test harness program to crash, it
is necessary to debug the driver code either by eye or using SDBG. Debugging by eye should always
be the first resort, however, whenever the bug can be readily pinned down to a particular vector.
Things to look out for include:
e ~=An unbalanced stack: Check that the number of 'pushes' equals the number of 'pops' in the
appropriate vector code.
e Addressing the wrong location: Ensure that all the Channel status fields (stored in CS) are
offset using the correct register and that that register holds the right value. The following
code for instance requires DI to hold the address of the channel status struct prior to
invocation:
mov al, cs: [di].ChannelOpenFlag
e Consistency: With regard to the last point, it is important to be consistent if possible and try
and use the same register (i.e. DI) to hold the channel status structure. A different one
(usually BX) should also be used to hold the address of the open channel control block.
e Trashing BX and DI: If these registers are used in the vector code for anything other than
addressing, check that their value is not being trashed by the operation.
Debugging using SDBG is an extension of debugging by eye. The SIBO debugger allows the
programmer to trace through the driver's source code instruction by instruction and observe the
contents of the CPU registers in the process. In this way it is possible to discover any discrepancies in
terms of the values stored in the various registers. Furthermore, tracing with SDBG will enable the
user to pinpoint the source of panics. The first objective of the device driver debugging process
should be to get the code outlined on the previous page to work OK.
Further Testing Strategies
Once installing, opening, closing and unloading are dealt with, a test harness can be expanded to
include p_iow or p_ioc calls which map onto the LDD's strategy vector. At this stage, SDBG is
particularly useful for testing purposes as breakpoints can be set and jumped to. In this way for any
p_ioc(serH, <func>, &serStat, &Al,&A2) call, the contents of the status word, serStat, and the A1
and a2 parameters can be tracked through the LDD's strategy vector. The value held by the status
word at the end of a particular strategy call is the value returned by the corresponding PLIB
p_iow/p_ioc call. Thus negative errors within the strategy code can be picked up by the test harness.
A good test harness should be able to catch all the possible errors and at the least invoke p_printf to
let the user know when one of them is returned. The file p_file.h contains a list of all the current
return error values and the corresponding PLIB level error name. The entry for PendingErr, for
instance is as follows:
#define PendingErr (-46)
#define E_FILE_PENDING PendingErr
In order to induce the return of these error values it is necessary to extend the basic test harness
outline to allow the user to undertake various pathological actions. For instance, the harness may
include code that tries to open a channel twice which should result in InUseErr being invoked. By
such means it is possible to ensure that a driver is not only operating as it should in normal
circumstances but returning the correct error value when relevant.
Memory Testing
The final process that should be undertaken to fully test a device driver consists of the construction of
an appropriate memory test harness. Three functions are presented on the next two pages which
provide the core of such a comprehensive memory test program. The first function, CheckMemory,
uses the PLIB routines p_allspce and p_sgfree to print out the current free bytes on the heap and the
number of free segments in the host RAM. This function can be invoked after installing, opening,
closing or removing a device driver to ensure that memory is not going to alloc heaven. The
GobbleMemory function is first used to determine the amount of free memory available in segments
Revision 1.00 Page 83 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
through calling p_sgfree. The PLIB p_sgcreate function is then invoked to create a new segment,
"Test", that consists of all of this free memory. Finally, the p_sgcopyto PLIB function is called to fill
"Test" with Ox55's. By using up all free memory in this way, it is possible to use segment "Test" to
determine whether a particular driver vector is writing to the wrong location. TestGobble, presented
overleaf, is the third function outlined. It uses the PLIB function p_sgcopyfr to check the values of
the bytes in the segment "Test". If any of the 0x55's have been overwritten then we know that we
have a problem. These three functions should be incorporated within the standard test harness
functions already presented in this chapter. In this way, it is possible to generate a powerful generic
test program that can be used as the basis for all device driver testing.
LOCAL_C VOID CheckMemory (VOID)
{
VOID *Heap;
INT fbytes;
fbytes=p_allspc (&Heap) ;
p_printf ("Free Heap Memory =>%x bytes", fbytes) ;
p_printf ("Free Segments =>%d",p_sgfree());
p_getch();
}
[KR KR KK KR KK KI KK IK I I I I /
LOCAL_C VOID GobbleMemory (VOID)
{
UINT nParas, segSize;
INT 3;
LONG pos,i;
UBYTE buf [256];
p_printf(" System RAM size = %d",p_getram());
p_printf ("Internal RAM usage = %d",p_sgramdisk())j;
nParas=p_sgfree()j;
p_printf ("Amount of free RAM = %d",nParas);
segH=p_sgcreate("Test",nParas, E_SEGMENT_HIGH) ;
if (segH)
p_printf ("Created segment \"test\"");
else
{
p_printf ("Error in creating segment");
p_getch();
p_exit (0);
}
segSize=p_sgsize(segH) ;
p_printf("Size of segment is %d",segSize);
p_printf("In 16-byte paragraphs");
p_sleep(5L);
for (j=0; j<16; j++)
buf [j]=0x55;
i=0;
while (i<segSize)
{
pos=i*16;
if (p_sgcopyto(segH, pos, &buf [0],16) <0)
{
p_printf ("Failed on p_sgcopy");
p_printf ("%d",i);
p_getch();
}
i++;
}
p_printf("Test segment full of 0x55s");
p_getch();
}
[RRR KK KK KK KKK IK I I I I /
Revision 1.00 Page 84 of 115 pages
The Psion SIBO Hardware Development Kit
LOCAL_C VOID TestGobble (VOID)
UINT segCount;
buf [16];
segCount=0;
p_printf ("Checking segment integrity ...");
for (segCount=0; segCount<p_sgsize(segH); segCount+t+)
{
if (p_sgcopyfr(segH, segCount*16, &buf [0] ,16) <0)
p_printf ("Error in segment");
else
{
for (i=0;i<16;i++)
if (buf[i] !=0x55)
{
p_printf ("OVERWRITE ERROR!");
p_printf ("Segment count=%d",segCount) ;
p_printf ("Byte count=%d",i);
}
}
}
p_printf ("Test segment OK");
p_printf ("Heap integrity checks OK");
p_allchk (44);
p_printf("If get here, heap OK");
p_getch();
}
[KR KR KK KR KK KKK I I I I I /
Revision 1.00
Psion PLC (c) May 1995
Page 85 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
APPENDIX: SOURCE CODE FILES
A4EXIF.ASM
title A4EXIF -- Example ASIC4 Interface device driver
subttl Copyright (c) Psion PLC (1994)
name A4EXIF
;
; VER DATE BY DESCRIPTION
jo -o--------------------------------------
7 1.00F 26/1/95 Mal Working Version
BUILDSB=1 7S3a build environment (channels=1)
S3c=0 ;Need to specify no s3c
; BUILDSC=1 7S3c build environment (channels=3)
; BUILDCH=1 ;HC build environment (channels=3)
; BUILDHH=1 753 build environment (channels=1)
include ..\inc\epoc.inc
include ..\inc\epoclib.inc
include ..\inc\epocsibo.inc
include ossibo.inc
include ospack.inc
Example Logical Device Driver for prototype LED-ASIC4 Interface
circuit for Corporate/S3C/Consumer serial port.
Written by Mal Dec 1994/Jan 1995.
Me oNe Ne
A4EXIF CONSTANTS AND TYPES
The following constants and type definitions
are compiler directives used by the TCEP assembler
when it is creating the LDD.
Ne Ne Ne Ne Ne
if Consumer
numberofchannels equ 1
else
if Corporate or S3c
numberofchannels equ 3
else
numberofchannels equ 2
endif
endif
7;Channel StatusEnt block accessed through CS:DI
A4ExifStatusEnt struc
A4ExifCSProcessId dw <i ;Channel parent process id
A4ExifCSChannelOpen db 2 ;Channel open flag
A4ExifCSChannelRunning db ? ;Channel hardware running
flag
A4ExifCSChanReadCompleted db 2 ;Channel request completed
flag
A4ExifCSChannelIntMask db 2 ;Channel interrupt mask
A4ExifCSChanneliIntNum db ? ;Channel interrupt number
A4ExifCSChannelSelect db 2 ;SIBO Channel select
A4ExifCSChanneliIntVec dw ? ;Channel int vector number
A4ExifCSTickHandle dw ee ;TCK channel handle
A4ExifCSA1Value db i ;Channel strategy Al parameter
A4ExifCSA2Value db ? ;Channel strategy A2 parameter
A4ExifStatusEnt ends
;Open Channel Control block accessed through DS:BX
A4ExifEnt struc
A4ExifDSIo ChanEnt <> 7;Open channel control block Ent
A4ExifDSHandlerPtr dw 2 ;Cant touch when under
A4ExifDSStatusPtr dw ? ;Hold, Resume, Reset or
A4ExifDSA1Ptr dw ? ;interrupt routine
A4ExifDSA2Ptr dw es
A4ExifDSStatusEntPtr dw ?
A4ExifEnt ends
A4PERIPH MASK equ Of0h 711110000b
Revision 1.00 Page 86 of 115 pages
The Psion SIBO Hardware Development Kit
EXTENDED_INFO_BYTE equ 090h
U5_ENABLE_ON equ 080h
U5_ENABLE_OFF equ 000h
;Latch addresses for reading/writing
USOUTPUT_LATCH equ 00000000b
U3INPUT_BUFFER equ 00000000b
U4STATUS_BUFFER equ 00000001b
cs: [di] .A4ExifCsAlValuefor
INTERRUPT_LATCH equ 00000001b
;Status byte masks
S2S3_ON equ 00000011b
S2S3_OFF equ 00000000b
S2_ONLY equ 00000001b
S3_ONLY equ 00000010b
INTERRUPT_STATUS_MASK equ 00000011b
7; LED bytes
SOME_LEDS_ON equ 01010101b
SOME_LEDS_OFF equ 10101010b
TOP_LEDS_ON equ 11110000b
BOTTOM_LEDS_ON equ 00001111b
ZERO_BYTE equ 00h
dgroup group stack
assume ds:dgroup,es:dgroup,ss:dgroup
CodeSeg
7 A4EXIF ENTRY TABLE
; Seseseo eee ee sececs
ProcBegin@ A4ExifLDD
; ssieceees
dw LDDSignature
db 'LED',0,0,0,0,0
dw (VectorEnd-Vector) /2
Vector:
dw A4ExifInstall
dw A4ExifRemove
dw A4ExifHold
dw A4ExifResume
dw A4ExifReset
dw A4ExifUnits
dw A4ExifOpen
dw A4ExifStrategy
VectorHandler:
dw A4ExifHandler
if Asic9
InterruptVectors:
dw A4ExifTickInt
endif
VectorEnd:
H A4EXIF INTERNAL DATA SPACE
,
; Device Driver global variables follow.
; These variables reside in the code segment
; and as such can always be accessed with
7 the 'cs:' prefix.
if Asic9
if Consumer
Channel0O A4ExifStatusEnt<0,0,0,0,mask
Psion PLC (c) May 1995
710010000b
7;Sets LBO for latch U5
;Deselects LBO for U5
;Selects
;Selects
;Selects
;Selects
A9MSlave, HwIrq2Revector, SelectChannel5, IntVec0O,0,0>
else
if Corporate or S3c
Channel0 A4ExifStatusEnt<0,0,0,0,mask
AOMExpIntA, HwIrq4Revector, SelectChannel3, IntVec0O,0,0>
Channell A4ExifStatusEnt<0,0,0,0,mask
AQMExpIntB, HwIrq5Revector, SelectChannel4, IntVec1,0,0>
Channel2 A4ExifStatusEnt<0,0,0,0,mask
A9MSlave, HwIrq2Revector, SelectChannel5, IntVec2,0,0>
Revision 1.00
AO for writing
AO for reading
; reading
Al for writing
Page 87 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
else
Channel0 A4ExifStatusEnt<0,0,0,0,mask
AOMExpIntA, HwIrq4Revector, SelectChannel3, IntVec0O,0,0>
Channell A4ExifStatusEnt<0,0,0,0,mask
AQ9MExpIntB, HwIrq5Revector, SelectChannel4, IntVec1,0,0>
endif
endif
else
if Consumer
Channel0O A4ExifStatusEnt<0,0,0,0,mask
Asic2Int, HwIrq4Revector, SelectChannel7, IntVec0,0,0>
else
if Corporate
ChannelO A4ExifStatusEnt<0,0,0,0,mask
ExpIntLeftA, HwIrq3Revector, ExpChannelLeftA, IntVec0O,0,0>
Channell A4ExifStatusEnt<0,0,0,0,mask
ExpIntRightB, HwIrq2Revector, ExpChannelRightB, IntVecl1,0,0>
Channel2 A4ExifStatusEnt<0,0,0,0,mask
Asic2Int, HwIrq4Revector, SelectChannel7, IntVec2,0,0>
else
ChannelO A4ExifStatusEnt<0,0,0,0,mask
ExpIntLeftA, HwIrq3Revector, ExpChannelLeftA, IntVec0O,0,0>
Channell A4ExifStatusEnt<0,0,0,0,mask
ExpIntRightB, HwIrq2Revector, ExpChannelRightB, IntVecl1,0,0>
endif
endif
endif
HoldFlag db 0 ;Hold/Resume flag
SwitchStatus db ? ;Holds the masked status byte from U4 after
interrupt
ProcEnd noret
ProcBegin@ A4ExifInstall, far
; eee
; Installs the device driver.
7 Invoked after a PLIB 'p_loadldd("A4EXIF.LDD")' call to load the LDD
; All of the fields inside the CS control blocks are preloaded
; with the correct values at install time. Install therefore does
; not do any work.
7 IN:
; Nothing
7 OUT:
; Carry Clear - driver successfully installed
7
cle ;The ChannelOpen fields are set to zero
ret ;in the relevant ChannelStatusEnt headers
ProcEnd noret
ProcBegin@ A4ExifRemove, far
; eSeseces eee
; Removes the device driver.
; Invoked after a PLIB 'p_devdel("LED",E_LDD) 'call to unload the
H device driver.
; A device driver cannot be removed if any of its channels
i are still open.
H IN:
; Nothing
H OUT:
; Carry clear - successfully removed
7 Carry set - remove failed, error number in AL
7
mov cx, numberofchannels ;Check that each
mov di, offset Channel0O ;channel is closed
xor ax, ax
CheckAl1lChannelsClosedLoop:
cmp cs: [di] .A4ExifCSChannelOpen, al ;Closed channels will
jne WeHaveAChannelOpenSoFail ;have the value 0 in
add di, (size A4ExifStatusEnt) ;their ChannelOpen
Revision 1.00 Page 88 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
loop CheckAl1ChannelsClosedLoop ;flags
jmp FinishedOkay
WeHaveAChannelOpenSoFail:
mov al, InUseErr ;Fail if not all
stc ;closed
ret
FinishedOkay:
cle
ret
ProcEnd noret
ProcBegin@ A4ExifHold, far
v
; Called by the operating system whenever the device driver is
; being moved or the machine is powering down.
; This will also be called by our pack door polling function when
; it sees that the doors have been opened and our peripheral has
; lost power.
; IN:
7 Reason for the hold in AH
7 OUT:
7 Nothing
13
mov cx, 1 ;Hold can be called
xchg cl, HoldFlag ;when the driver is
cmp cl, 0 ;under a hold so
jne AlreadyHeld ;re-entrancy blocking
A4HoldFromTick: ;is required
mov cx, numberofchannels
mov di, offset Channel0 ; Loop because Hold
HoldAllTheChannelsLoop:
;must stop all the
cmp cs: [di] .-A4ExifCSChannelOpen, ; channels
je DontHoldBecauseNotOpen ;Is the channel open?
push cx ;If it is then stop
call StopTheChannelRunning yall interrupts
pop cx
DontHoldBecauseNotOpen:
add di, (size A4ExifStatusEnt)
loop HoldAl1lTheChannelsLoop
AlreadyHeld:
ret
ProcEnd noret
ProcBegin@ A4ExifResume, far
3 Called by the operating system when it has finished moving the
- device driver in memory or when the machine is switching back on.
; Also called by our door polling routine when it sees that the doors
; have been closed and we can resume communication with our peripheral.
; IN:
iH Nothing
; OUT:
7 Nothing
is
xor CX, cx ;Block in case of re-entrancy
xchg cl, HoldFlag
cmp cl, 0
je AlreadyResumed
if Asic9
GenDataSegment ;Check to see if the pack
HwGetSsdData ;doors are still closed
mov bx, ax
cmp es: [bx] .SsdDoorStatus, DoorOpen
je DoorsAreOpen
endif
A4ResumeFromTick:
mov cx, numberofchannels ; Loop because resume must
mov di, offset Channel0 ;restart each open channel
ResumeAllTheChannelsLoop:
cmp cs: [di] .A4ExifCSChannelOpen, 0 ;Is the channel open?
je DontResumeBecauseNotOpen
push Cx
call StartTheChannelRunning
pop cx
DontResumeBecauseNotOpen:
add di, (size A4ExifStatusEnt)
loop ResumeAl1lTheChannelsLoop
AlreadyResumed:
Revision 1.00 Page 89 of 115 pages
The Psion SIBO Hardware Development Kit
Psion PLC (c) May 1995
ret
DoorsAreOpen:
mov HoldFlag, 2
ret
ProcEnd noret
ProcBegin@ A4ExifReset, far
Called when an application which opened a channel terminates without
closing the device driver.
A device driver, for each open channel, has to request that the
operating system calls this function when the application
terminates abnormally (ie without closing an open channel).
Reset can supply one piece of identifying data which will be
passed in CX. This would usually be the channel's number or CS
control block pointer.
Reset just needs to clear interrupts, hardware reservations, and free
the channel. Any allocated space will be cleaned up for you by the OS.
IN:
The device driver's handle in BX
The address of the status struc identifying the channel in CX
7 OUT:
; Nothing
,
mov di, cx
cmp cs: [di] .A4ExifCSChannelOpen, 0
je NotOpenToReset
call StopTheChannelRunning 7Stop interrupts
mov al, cs: [di] .A4ExifCSChannelIntMask ;Free the reserved
HwF reeChannel ;hardware
mov cs: [di] .A4ExifCSChannelOpen, 0 ;The channel is now
NotOpenToReset: ;free
ret
ProcEnd noret
ProcBegin@ A4ExifUnits, far
Called to find how many open channels the driver will support
- In:
; Nothing
- Out:
H The total number of channels supported in AX
,
mov ax, numberofchannels
ret
~
ProcEnd noret
ProcBegin@ A4ExifOpen, far
Opens a device driver channel.
Invoked after the PLIB call 'p_open(é&appHandle, "LED:*",-1)'to open a
channel to the device driver.
,
,
7
H Tn:
; OS device handle of the device driver in DX
; Pointer to the OpenEnt struc in SI
; Pointer to the IntEnt struc in BP
; DS,ES,SS point to the applications data space
i Out:
; Carry clear - BX holds the address of the open channel
7 Carry set - AL holds the error number
is
cld ;Interrupts off to
pushf ;prevent multiple apps
oli ;calling open
mov si, [si] .OpenNamePtr ; Simultaneously
mov al, [sitl]
CharToFoldedChar ;Read the unit no.
cmp al, 'A' ;part of device name
jb OpenNameErr ;to find which channel
sub al, 'A' ;to open. eg "LED:A"
cmp al, numberofchannels
jae OpenNameErr
xor ah, ah
push ax ;Map the channel no.
mov dx, (size A4ExifStatusEnt) ;to a channel control
mul dx ;block in our CS
pop ax 7; space
Revision 1.00
Page 90 of 115 pages
The Psion SIBO Hardware Development Kit
mov di, ax
add di, offset Channel0O
cmp cs: [di] .A4ExifCSChannelOpen, 0
je GetATickChannel
popft
mov ax, AlreadyOpenErr
jmp ChannelAlreadyOpen
GetATickChannel:
mov cs: [di] .A4ExifCSChannelOpen, 1
mov cs: [di] .-A4ExifCSChannelRunning, 0
popft
ife Asic9
jmp GetHardwareChannel
else
push ax
mov ax, ((':' shl 8)+'K')
push ax
mov ax, (('C' shl 8)+'T')
push ax
mov bx, sp
ToOpen
jne GotATickChannel
add sp, 6
mov ax, LockedErr
jmp OpenFailed
GotATickChannel:
add sp, 6
mov cs: [di] .A4ExifCSTickHandle, ax
push ax
mov bx, ax
mov ax, IoFuncStart
mov ex, 1
push cx
push cx
push ax
mov cx, (InterruptVectors-Vector) /2
push cx
mov cx, sp
ToWithWait
add sp, 8
pop dx
jmp GetHardwareChannel
endif
OpenNameErr:
popft
mov ax, NameErr
jmp ChannelAlreadyOpen
GetHardwareChannel:
mov al, cs: [di] .A4ExifCSChannelIntMask
HwGetChannel
jne CheckHardwareNowThatSIBOChannellIsOpen
mov ax, InUseErr
jmp FreeTckAndExit
FreeTckAndChannelHardware:
mov al, cs: [di] .A4ExifCSChannelIntMask
HwF reeChannel
mov ax, DeviceErr
FreeTckAndExit:
if Asic9
push ax
mov bx, cs: [di] .A4ExifCSTickHandle
IoClose
pop ax
endif
OpenFailed:
mov cs: [di] .A4ExifCSChannelOpen, 0
ChannelAlreadyOpen:
stc
OpenExit:
ret
CheckHardwareNowThatSIBOChannellIsOpen:
Proclid
mov cs: [di].A4ExifCSProcessId, ax
mov cs: [di] .A4ExifCSChanReadCompleted, 0
call CheckHardwarePresent
jc FreeTckAndChannelHardware
mov cx, (size A4ExifEnt)
HeapAllocateCell
jc FreeTckAndChannelHardware
mov bx, ax
Revision 1.00
Psion PLC (c) May 1995
;Offset in DI
;Check to see if
;channel is already
;open
,Obtain a TCK channel so
;we can poll the door state
7;If HC, we don't need
;to set up the TCK
; routine
;Try to open "TCK:"
;channel with "TCK:"
; string on stack
;TCK will call our
,door-polling function
732 times a second
7Start our
,door-polling function
;running by starting
;the "TCK:" channel
7Frequency 1 tick
;Data irrelevant
;Handle to driver
;TCK function to call
7;Check the hardware
;is available then
;reserve it
;Returns with carry
;clear if OK
7Set up the calling
;process ID
;Returns with carry
;clear if successful
;Allocate a control
;block in our app's
;data space
Page 91 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
push bx ;IloAddHandler trashes BX
mov al, (VectorHandler-Vector) /2 ;Set up our wait handler
ToAddHandler ;Leaves the address of
pop bx ;handler in AX
jne GotHandler
push ax ;If no handler, open fails
HeapFreeCell
pop ax
jmp FreeTckAndChannelHardware
GotHandler:
mov [bx] .A4ExifDSStatusEntPtr, di
mov [bx] .A4ExifDSHandlerPtr, ax
mov [bx] .A4ExifDSStatusPtr, 0
mov [bx] .A4ExifDSIo.ChanNext, bx
mov [bx] .A4ExifDSIo.ChanSignature, IoChanSignature
mov [bx] .A4ExifDSIo.ChanLibHandle, dx
mov cx, al ; loRequestReset takes
xchg bx, dx ;the device handle in
IoRequestReset 7BX and the channel
xchg bx, dx ;handle in CX
xor ax, ax
call StartTheChannelRunning
ReturnCLc:
cle
ret
ProcEnd
if Asic9
ProcBegin@ A4ExifTickInt, far
This function is called by the tick handler on every tick of
; the system clock. This happens 32 times a second.
; The operating system will call a device driver to hold when memory is
; being moved and when the machine is being powered down. It will not
; call the device driver when the pack doors are opened.
Opening the pack doors will cause power to the peripheral to be cut,
;
; and therefore the driver needs to be held in the way it would be if
; the machine powered down. Only for Asic9 based machines.
; This function checks the state of the doors on every tick and calls
iH Hold and resume when it sees the status of the doors change.
H IN:
; The state of the door in SI
; OUT:
; Nothing
;
cmp si, DoorOpen 7Is the door open
je TheDoorIsOpen 7or closed?
cmp HoldFlag, 2 7Closed Door, HoldFlag=2
je NeedToDoTheResume ;means we do a resume
ret 7Closed Door, HoldFlag!=2
NeedToDoTheHold:
mov HoldFlag, 2
jmp A4HoldFromTick
NeedToDoTheResume:
mov HoldFlag, 0
jmp A4ResumeFromTick
TheDoorIsOpen:
xor ax, ax
cmp HoldFlag, al
je NeedToDoTheHold
ret
ProcEnd noret
endif
ProcBegin@ A4ExifHandler, far
;
; When an application is waiting within an iowait and a signal is
; generated then before passing that signal to the application the
: OS first runs any wait handlers belonging to the device driver
; channels that the application has open.
; The interrupt routine can generate a signal but cannot fill in any
; status words or pass values back to the application because the
; applications DS space is not available. The handler can consume a
; signal generated by an interrupt and then fill any status words
7 before re-signalling the application. A handler always has access
; to the application's DS space. The wait handler can consume the
7 signal which is then no longer passed back to the application.
Hi IN:
Revision 1.00 Page 92 of 115 pages
The Psion SIBO Hardware Development Kit
Ne Ne Ne Ne
Psion PLC (c) May 1995
Pointer to our control block in applications DS space in BX
DS,ES,SS point at application's data space
OUT:
Carry clear - do not consume the signal, signal not for us
7 Carry set - consume the signal, re-enable handler if AL
; non-zero else don't re-enable handler if AL=0.
7
cld
pushf
cli
mov di, [bx].A4ExifDSStatusEntPtr ;Is the signal for us?
cmp cs: [di] .A4ExifCSChanReadCompleted, 1
jne ExitHandlerSignalNotForuUs ;If it is, copy
mov cs: [di] .A4ExifCSChanReadCompleted, 0 ;the values read in
mov al, cs: [di] .A4ExifCSA1Value ;the interrupt
mov ah, cs: [di] .A4ExifCSA2Value ;routine back to
mov di, [bx].A4ExifDSA1Ptr ;the application
mov [di], al ;Asynchronous read
mov di, [bx].A4ExifDSA2Ptr ;has been completed
mov [di], ah
xor di, di
xchg [bx] .A4ExifDSStatusPtr, di ;Clear the status
mov word ptr [di], 0 ;word
popft
ToSignal
xor ax, ax
stc ;STC and AL!=0 =>
ret ;consume signal and
ExitHandlerSignalNotForus: ;don't re-enable
popft ;handler
elec
ret
ProcEnd
StrategyVectorTable label word
dw offset A4ExifDefault ;StrategyPanic
dw offset A4ExifRead 7 StrategyRead ie P_FREAD
dw offset A4ExifWrite ;StrategyWrite ie P_FWRITE
dw offset A4ExifClose ;StrategyClose ie P_FCLOSE
dw offset A4ExifCancel 7 StrategyCancel ie P_FCANCEL
dw offset A4ExifDefault ;StrategyAttach
dw offset A4ExifDefault ;StrategyDetach
dw offset A4ExifSet ;StrategySet ie P_FSET
dw offset A4ExifSense ;StrategySense ie P_FSENSE
ProcBegin@ A4ExifStrategy, far
Called by the operating system when an I/O request is made on
the device driver.
Calls to this funcion from an owning application will usually take
the form p_ioc(pcb, func, &Stat, &Al, &A2) ;
The strategy function is called with a function number specifying
the action which the driver is to take, a status word to fill when
the action is complete, and two arguments Al and A2.
Nee Ne Ne
Se ee
All strategy functions must complete with a signal to the application.
Functions can be asynchronous and need not complete immediately.
IN:
Pointer to our control block in the applications DS in BX
7 Device driver handle in DX
; Pointer to the RqEnt struct in SI
; Pointer to a IntEnt struct in BP
; DS,ES,SS point at the applications data space
i OUT:
; Returned value in AX
; Must call IoSignal somewhere to signal completion
; of the I/O request.
v
mov ax, [si].RqFunction ;Get the function number
mov dx, [si].RqAlPtr ;DX holds the first argument
mov di, [si].RqStatusPtr ;for convenience
mov word ptr [di], PendingErr 7Status word holds
shl ax, 1 ; E_FILE_PENDING
mov di, ax
push StrategyVectorTable[di] ;Jump to required function
mov di, [bx] .A4ExifDSStatusEntPtr ;with our CS control block
retn ;pointer in DI
A4ExifDefault:
ToRoot
Revision 1.00
Page 93 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
ret
ExitWithCompletionStatusZero:
xor ax, ax ;Common exit points
ExitWithOtherCompletionStatus:
mov di, [si].RqStatusPtr
mov word ptr [di], ax
ToSignal
ExitStillPending:
xOr ax, ax
cle
ret
ProcEnd noret
STRATEGY VECTOR TABLE FUNCTIONS
IN:
DX holds the pointer to the first argument in 'p_iow(...)' call
BX holds the address of the open channel control block
CS:DI holds the address of status struc identifying the open channel
See eee Ty
ProcBegin@ A4ExifRead, far
H Strategy vector table function that handles asynchronous byte reads
7 from the LEDs and switches.
i; The corresponding PLIB call is p_ioc(pcb,P_FREAD, &Stat, &Argl, &Arg2) ;
; The request is completed when the interrupt routine signals the
; handler which in turn signals the application passing back the values
; read at the time of the interrupt through the AlPtr and A2Ptr.
H IN:
; Pointer to control block in applications data space in BX
i Pointer to control block in our CS space in DI
; Al (pointer to Argl) in DX
,
v
OUT:
Jumps to common exit point
. Panics if multiple requests
,
cmp [bx] .A4ExifDSStatusPtr, 0 ;Panic if we already
jne PanicPending ;have an I/O read request
pushf ;pending on the channel
cli ;Disable interrupts
mov cs: [di] .A4ExifCSChanReadCompleted, 2
mov ax, [si].RqA1Ptr
mov [bx] .A4ExifDSA1Ptr, ax ; Store the locations to
mov ax, [si].RqA2Ptr ;put the data when we get it
mov [bx] .A4ExifDSA2Ptr, ax
mov di, [si].RqStatusPtr
mov [bx] .A4ExifDSStatusPtr, di ;DI holds the address
mov word ptr [di], PendingErr 7of status word and we
popf ;Signal that we are waiting
mov bx, [bx] .A4ExifDSHandlerPtr ;for completion of read
mov cl,
ToEnableHandler ;Enable Wait Handler
jmp short ExitStillPending 7No IoSignal because
PanicPending: ;we are still waiting
mov al, PaniclIoPending
ProcPanic
ProcEnd noret
ProcBegin@ A4ExifWrite, far
This function sets the state of the LEDs.
It completes immediately after setting the state as it has nothing
to wait for.
Write is the same as set.
Ne Ne Ne Ne Ne te
IN:
; Pointer to control block in applications data space in BX
; Pointer to control block in our CS space in DI
. Al in DX
- OUT:
- Jumps to Set
,
jmp WriteAndSetAreTheSame
ProcEnd noret
ProcBegin@ A4ExifClose, far
Revision 1.00 Page 94 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Handles the request to close a channel.
called by the PLIB call p_iow(pcb,P_FCLOSE) or p_close (pcb)
Ne Ne Ne Ne
IN:
Pointer to control block in applications data space in BX
; Pointer to control block in our CS space in DI
; OUT:
; Jumps to common exit point
,
call StopTheChannelRunning 7Stop interrupts
if Asic9
push bx ;Close down the
mov bx, cs: [di] .A4ExifCSTickHandle 7;"TCK:" channel
IoClose
pop bx
endif
push bx
mov ax, [bx] .A4ExifDSIo.ChanLibHandle ;Remove the wait
push ax ;handler
mov bx, [bx] .A4ExifDSHandlerPtr
IoRemoveHandler
cmp cs: [di] .A4ExifCSChanReadCompleted, 0 ;If the interrupt
je NoSignalToConsumeFromInterrupt ;has signalled the
ToWaitForSignal ;handler we need to
NoSignalToConsumeFromInterrupt: ;consume its signal
pop bx ;now the handler
mov cx, di ;has been removed
ToRequestResetCancel
pop bx 7No longer need reset
HeapFreeCell ;Free our control
mov al, cs: [di] .-A4ExifCSChannelIntMask ;block in app's DS
HwFreeChannel
mov cs: [di] .A4ExifCSChannelOpen, 0
jmp ExitWithCompletionStatusZero 7To signal completion
ProcEnd noret 7,of close request
ProcBegin@ A4ExifCancel, far
v
; Cancel any pending asynchronous read.
; Called by the PLIB function p_iow(pcb,P_FCANCEL) ;
i In:
; Pointer to control block in applications data space in BX
; Pointer to control block in our CS space in DI
; Out:
; Jumps to common exit point
7
pushf
cli
cmp [bx] .A4ExifDSStatusPtr, 0 ;Check that there is
je NothingToCancel ya request pending
push bx
mov bx, [bx] .A4ExifDSHandlerPtr
sub cl ol
ToEnableHandler ;Disable Wait Handler
pop bx
cmp cs: [di] .A4ExifCSChanReadCompleted, 1
jne NoSignalFromInterrupt ;TO consume any stray
ToWaitForSignal ;Signal from the
NoSignalFromInterrupt: ;interrupt routine
mov cs: [di] .A4ExifCSChanReadCompleted, 0
xor fomcramre be ;To signal completion
xchg di, [bx].A4ExifDSStatusPtr ;of the outstanding
mov word ptr [di], CancelErr pasync read request
ToSignal ;Signal to p_waitstat
NothingToCancel:
popft
jmp ExitWithCompletionStatusZero 7To signal completion
ProcEnd noret 7of the cancel request
ProcBegin@ A4ExifSet, far
,
7 Write a value to the LED latch.
; Can be called by the PLIB call p_iow(pcb,P_FSET, &Argl); where Al
; is an unsigned byte.
; Write is the same as set.
7 IN:
; Pointer to control block in applications data space in BX
7 Pointer to control block in our CS space in DI
7 Al (pointer to Argl) in DX
Revision 1.00 Page 95 of 115 pages
The Psion SIBO Hardware Development Kit
OUT:
Jumps to common exit point
,
WriteAndSetAreTheSame:
Steere Ty
Ne Ne Ne Ne
seo
pushf
cli
mov al, cs: [di] .-A4ExifCSChannelSelect
HwSelectChannel
push ax
mov bx, dx
mov dl, U50UTPUT_LATCH
mov al, [bx]
call OutputByte
pop ax
HwSelectChannel
popft
jmp ExitWithCompletionStatusZero
ProcEnd noret
ProcBegin@ A4ExifSense, far
Reads the state of the LEDS and Switches.
Psion PLC (c) May 1995
7Select our SIBO
; serial channel
7Store old channel
;DX (now BX) points
;to the value to
output to our
;peripheral
;Return old channel
;To signal completion
7of set request
Can be called from PLIB using p_iow(pcb, P_FSENSE, éArgl, &Arg2)
Where Argl and Arg2 are unsigned bytes.
In:
Pointer to control block in applications data space in BX
Pointer to control block in our CS space in DI
Al (pointer to Argl) in DX
Out:
Jumps to common exit point
pushf
cli
mov al, cs: [di] .-A4ExifCSChannelSelect
HwSelectChannel
push ax
mov bx, dx
mov dl, U4STATUS_BUFFER
call InputByte
mov [bx], al
mov bx, [si] .RqA2Ptr
mov dl, U3INPUT_BUFFER
call InputByte
mov [bx], al
pop ax
HwSelectChannel
popft
jmp ExitWithCompletionStatusZero
ProcEnd noret
LOCAL DEVICE DRIVER FUNCTIONS
7Select our SIBO
;serial channel
7 Store old channel
;DX (now BX) points
;to the variable in
;which to place the
;value read from U4.
7BX now points to
;the variable in
;which to place the
;value read from U3.
;Return old channel
;To signal completion
;of a sense request
Interrupts must be off prior to the call to this function.
IN:
DL has address to which Asic4 is to write
AL holds the value to output
mov al, (SerialWriteSingle or A4Address)
SBUSY
SCONTOUT
mov al, dl
SBUSY
SDATAOUT
mov al, (SerialReadSingle or A4Data)
SBUSY
SCONTOUT
SBUSY
SDATAIN
ret
ProcEnd noret
ProcBegin@ OutputByte
Interrupts must be off prior to the call to this function.
Revision 1.00
Page 96 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
H IN:
; DL has address to which Asic4 is to write
; AL has the value to output
mov al, (SerialWriteSingle or A4Address)
mov al, dl
mov al, (SerialWriteSingle or A4Data)
SBUSY
SCONTOUT
SBUSY
XNOP
pop ax
SDATAOUT
ret
ProcEnd noret
ProcBegin@ IntVecO, far
- Interrupt on serial channel0
3 Calls Comint with channel control block pointer in DI
,
mov di, offset Channel0O
jmp ComIint
ProcEnd noret
if Corporate or S3c
ProcBegin@ IntVecl1, far
Sat
Interrupt on serial channell
; Calls Comint with channel control block pointer in DI
,
mov di, offset Channell
jmp ComInt
ProcEnd noret
ProcBegin@ IntVec2,far
Interrupt on serial channel2
Calls Comint with channel control block pointer in DI
Ne Ne Ne Ne
mov di, offset Channel2
7 FALL THROUGH
ProcEnd noret
endif
ProcBegin@ ComInt, far
,
; The common interrupt service routine code.
; When an interrupt occurs, the first task is to read the status
7 buffer of latch U4. The subsequent action is dependent on the
; postion of switches Sl and S2. For the purposes of this example,
; the four posibilities for the switch values correspond somewhat
; arbitrarily to four different byte values that are written to U5.
; in the 8086, interrupts cannot occur while in an interrupt routine.
; If an asynchronous read is pending then the handler is signalled.
7 IN:
; Channel's CS based control block pointer in DI
,
cmp cs: [di] .A4ExifCSChanReadCompleted, 2 ;Only if 2 do we have
jne NotAsynchronousRead ;asynch read completed
mov cs: [di] .A4ExifCSChanReadCompleted, 1
mov bx, cs: [di] .A4ExifCSProcessId ;Signals completion
ToSignalByPidNoReSched 7Of read to OS so as
NotAsynchronousRead: ;to invoke handler
mov al, cs: [di] .-A4ExifCSChannelSelect
HwSelectChannel
push ax
mov dl, U3INPUT_BUFFER
call InputByte
mov cs: [di] .A4ExifCSA2Value, al ;LED byte
mov dl, U4STATUS_BUFFER
Revision 1.00 Page 97 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
call InputByte
mov cs: [di] .A4ExifCSAlValue, al ; Status byte
and al, INTERRUPT_STATUS_MASK
xchg al, SwitchStatus
cmp SwitchStatus, S2S3_ON 7;S2 and S3 on => turn
je A11LEDsOn 7on alternate LEDs
cmp SwitchStatus, S2S3_OFF 7S2 and S3 off => not
je A11LEDsOff ;the alternate LEDs
cmp SwitchStatus, S2_ONLY 782 on, S3 off => turn
je TopLEDsOn 7on top four LEDs
cmp SwitchStatus, S3_ONLY 753 on, S2 off => turn
je BottomLEDsOn 7on bottom four LEDs
ErroriInSwitchStatusByte:
jmp ClearInterruptAndReschedule
A11LEDsOn:
mov al, SOME_LEDS_ON
jmp Output LEDByte
A11LEDsOff:
mov al, SOME_LEDS_OFF
jmp Output LEDByte
TopLEDsOn:
mov al, TOP_LEDS_ON
jmp Output LEDByte
BottomLEDsOn:
mov al, BOTTOM_LEDS_ON
OutputLEDByte:
mov dl, US50UTPUT_LATCH
call OutputByte
ClearInterruptAndReschedule:
mov dl, INTERRUPT_LATCH
call OutputByte
if Asic9 ;A write to this location
out A9BNonSpecificEoiw, al ;informs the interrupt
else ;controller that the
out AlNonSpecificEoi, al ;installed interrupt
endif ;service routine has
pop ax ; finished
HwSelectChannel
onlkres ;Reschedule if necessary
ret
ProcEnd noret
ProcBegin@ StartInterrupts
po SSS SES
; Start interrupts assuming interrupts are
; off prior to call.
; The EPOC GenSetRevector service loads in
; a user-specified interrupt service routine
; located at the address given in cx:bx
; (segment cx, offset bx) for the interrupt
; vector number given in AL. Note that the
7 variable A4ExifCSChannelIntVec holds the
; name of the appropriate required interrupt
; vector routine for the channel.
H IN:
; Our CS control block pointer in DI
H OUT:
i; Nothing
is
mov al, cs: [di] .-A4ExifCSChannelIntNum 7Get the OS to call
mov cx, CS ;the function in
push bx 7CS:BX every time
mov bx, cs: [di] .A4ExifCSChannelIntVec ;that the interrupt
GenSetRevector ;whose number is in
pop bx 7;AL occurs
ife Asic9
in al, AlInterruptMask
or al, cs: [di] .A4ExifCSChannelIntMask ;Set the mask
out AlInterruptMask, al ;location so as
; interrupt
else ;to enable that
in al, A9BInterruptMaskRW ; interrupt
or al, cs: [di] .A4ExifCSChannelIntMask
out A9BInterruptMaskRW, al
endif
ret
ProcEnd noret
Revision 1.00 Page 98 of 115 pages
The Psion SIBO Hardware Development Kit
ProcBegin@ StopInterrupts
; Stop interrupts assuming that interrupts are off
The EPOC GenResetRevector OS service
interrupt service routine with the original
routine and interrupt mask for the vector
given in AL.
IN:
Our CS control block pointer in DI
Se ee Te
OUT:
; Nothing
ife Asic9
replaces the previously loaded user-specified
Psion PLC (c) May 1995
in al, AlInterruptMask ;Disable the
mov ah, cs: [di] .A4ExifCSChannelIntMask ; interrupt
not ah
and al, ah
out AlInterruptMask, al
else
in al, A9BInterruptMaskRW
mov ah, cs: [di] .A4ExifCSChannelIntMask
not ah
and al, ah
out A9BInterruptMaskRW, al
endif
mov al, cs: [di] .-A4ExifCSChannelIntNum ;Return the interrupt
GenResetRevector ;vector to the OS
ret ; default
ProcEnd noret
ProcBegin@ StartTheChannelRunning
Fo eee eeeeeeea=
; Starts the hardware and interrupts going
; If the hardware is aready running then there is nothing to do
; Must check that the hardware has not vanished before restarting it
H IN:
; Our CS control block pointer in DI
7 OUT:
i Nothing
7
pushf
cli
cmp byte ptr cs: [di].A4ExifCSChannelRunning, 0
jne ChannelAlreadyRunning
call CheckHardwarePresent
jc HardwareNotPresent
mov al, cs: [di] .-A4ExifCSChannelSelect
HwSelectChannel
push ax
mov al, (SerialWriteSingle or A4Control) ; Switch on the
SBUSY output latch U5
SCONTOUT ;by asserting
mov al, U5_ENABLE_ON ;the ASIC4 LBO line
SBUSY ; (LBO is inverted)
SDATAOUT
xor ax,ax
mov dl, INTERRUPT_LATCH 7Clear any pending
call OutputByte ;interrupt on the
mov dl, US5OUTPUT_LATCH ;peripheral
call OutputByte 7Preset the LEDs
pop ax ;to all off
HwSelectChannel
call StartInterrupts
mov cs: [di] .A4ExifCSChannelRunning, 1
ChannelAlreadyRunning:
popft
cle
ret
HardwareNotPresent:
popft
stc
ret
ProcEnd noret
ProcBegin@ StopTheChannelRunning
Revision 1.00
Page 99 of 115 pages
The Psion SIBO Hardware Development Kit
Ne Ne Ne Ne
Stops the hardware and interrupts
Psion PLC (c) May 1995
Checks to see if the hardware is really running to start with
IN:
Our CS control block pointer in DI
i OUT:
; Nothing
7
pushf
cli
cmp byte ptr cs:[di].A4ExifCSChannelRunning, 0
je ChannelNotRunning
mov al, cs: [di] .-A4ExifCSChannelSelect
HwSelectChannel
push ax
mov al, (SerialWriteSingle or A4Control)
SBUSY
SCONTOUT
mov al, U5_ENABLE_OFF
SBUSY
SDATAOUT
xor ax, ax
mov dl, US50OUTPUT_LATCH
call OutputByte
pop ax
HwSelectChannel
call StopInterrupts
mov cs: [di] .A4ExifCSChannelRunning, 0
ChannelNotRunning:
popft
ret
Se eT
ProcEnd noret
ProcBegin@ CheckHardwarePresent
Used to determine whether the correct hardware is present
on the successfully procured serial channel.
IN:
CS control block pointer in DI
OUT:
Carry clear - correct hardware is there
Carry set - wrong or no hardware
pushf
cli ;Select the correct
mov al, cs: [di] .A4ExifCSChannelSelect ;SIBO channel that
HwSelectChannel ;the peripheral is
push ax ;attached to
HwNullFrame
mov al, (SerialSelect or Asic4Id)
SBUSY ;First look for an
SCONTOUT 7;ASIC4 at the other
XNOP ;end of the link
SBUSY
SDATAIN ;Ilf the returned
test al,al ;value is non-zero
je ConnectionFailedA4NotPresent ;we have an ASIC4
mov al, (SerialReadSingle or A4InfoR)
SBUSY ;Now see if we have
SCONTOUT ;the right peripheral
XNOP 7;XNOP allows the busy
SBUSY 7Signal to come
SDATAIN ;through for the wait
and al, A4PERIPH_MASK
cmp al, EXTENDED_INFO_BYTE ;Mask out the bottom
jne ConnectionFailed ;four bits as the
pop ax yupper four contain
HwSelectChannel ;the peripheral ID
popft
cle ;If it is our hardware
ret 7exit with carry clear
ConnectionFailedA4NotPresent:
mov al, (SerialSelect or Asic5Normalld) ;Its not an ASIC4
SBUSY ;peripheral
SCONTOUT 7By selecting a non
XNOP 7;ASIC4 as an ASIC4,
SDATAIN ;we effectively
test al,al
Revision 1.00
;disable whatever is
Page 100 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
jne ConnectionFailed yout there so we do
mov al, (SerialSelect or Asic5PackId) ja select for all
SBUSY ;possibilities so
SCONTOUT ;that we don't end
XNOP ;up disabling
SDATAIN yanything that we
test al,al ;can't control.
jne ConnectionFailed
mov al, (SerialSelect or Asic8Id) 7Modem chip id
SBUSY
SCONTOUT
XNOP
SDATAIN
ConnectionFailed:
pop ax
HwSelectChannel
popft
stc
ret
ProcEnd noret
EndCodeSeg
stack segment stack para 'data'
stack ends
end A4ExifLDD
Revision 1.00 Page 101 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
SYSS$AS5.ASM
title ASSPDD Epoc Serial physical device driver for the 16550
subttl Copyright Psion PLC 1993
name SYSSAS5
i VERSION DATE DESCRIPTION
me MEE ee ee ee eee
; Lat 08/12/94 Initial version
7 Written by Jason December 1994
: Serial Driver for Epoc based around ASIC5
Sr5s3 = 0
Sr5S3a = 1
ifdef BUILDS3
Sr5S3 = 1.
Sr5S3a = 0
BUILDHH equ 1
endif
a Sr5S3a
BUILDSB equ 1
endif
include ..\inc\epoc.inc
include ..\inc\epocser.inc
include ..\inc\epoclib.inc
include ..\inc\epocsibo.inc
include ..\srcs\ossibo.inc
include ..\srces\ospack.inc
Sr5ChannelStruct struc
Sr50pen db ? ; Is the channel open
SrKSCtY1L db ? ; State of control lines
Sr5IntVector db 2 ; The Vector number
Sr5Channel db ? ; Which channel are we
Sr5Mask db ? ; InterruptMask
Sr5Running db ; Are we running
Sr5IntRoutineVec dw cs ; Vector to Interrupt
Sr5Baud dw ? ; The baud rate
Sr5LddData dw ? ; Info from Ldd above
Sr5StatusInt dd ? ; Vectors in serial
Sr5Recvint dd 2 ; Above to be called
Sr5XmitInt dd ? ; On input/output
Sr5ClockEnable db ? ; Reason to stop
Sr5TheLines db ? ; State of the modem lines
Sr5ChannelStruct ends
A5Ent struc
A5PortA
A5PortB
A5PortBMode
A5PortD
A5Swipel
A5Swipe2
A5IntMask
A5CtrlReg
A5USR
A5RHR
A5BDLSB
A5SBDMSB
A5MCRIEoi
A5MCRPresentEoi
A5MCR2Eoi
ASDUMMYF
A5Ent ends
Lt Consumer
NumberOfChannels
else
NumberOfChannels
endif
OsActivityMeter
StopTimeOut
S_RS2320N
Revision 1.00
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
equ
equ
equ
equ
equ
VVV Vv vw
YN vn vv
158ch
1000
00000001b
at
ASIC5 Read/Write
Port A R/W
Port B R/W
Inc/Mode
Port CD Write only
Ne Ne Ne Ne Ne
Interrupt mask R/W
IntType/Ctrl register
UART Status/Ctrl
Receive/Transmit
Baud Rate write only
Baud Rate write only
MCR shift register
Barcode data&ints
Ne Ne Ne Ne
; S3 Single Channel
, HC,S3C Three Channel
; Activity Channel
; w~ls (1000ms) wait
7 RS232 on
Page 102 of 115 pages
The Psion SIBO Hardware Development Kit
Psion PLC (c) May 1995
S_RSTTLON equ 00000100b ; Line drivers on
S_CENTON equ 00010000b ; Line drivers enable
S_RXENB equ 00000001b ; Receive interrupt on
S_TXENB equ 00000010b ; Transmit interrupt on
S_TXEMPTY equ 00010000b ; transmit buffer empty
S_RXINT equ 00000001b ; Receive interrupt?
S_TXINT equ 00000010b ; transmit interrupt?
S_MDINT equ 00000100b ; Modem status interrupt
S_CTS equ 00000001b # CLS
S_RTS equ 00000010b ; RTS
S_DCD equ 00000100b DCD
S_DSR equ 00000010b ; DCR
S_DTR equ 00000100b ; DIR
OVERRUN_ERROR equ 01000000b ; Character overrun
PARITY_ERROR equ 10000000b ; Parity error
S_PERIPHERALMODE equ 00000011b ; ASIC5 RS232 mode
S_UART_OFF equ 00000010b ; ASIC5 peripheral mode
dgroup group stack
assume ds:dgroup,es:dgroup,ss:dgroup
CodeSeg
ProcBegin@ OsAS5PDD
; SiS SeSe Sees Ses eceses
dw PDDSignature
db 'TTY.SR5',0
dw (VectorEnd-Vector) /2
Vector:
dw OsAS5SInstall
dw OsAS5Remove
dw OsAS50Open
dw OsAS5Strategy
VectorEnd:
BaudRateTable dw
-077f£h, -04£fh, -0368h, -02cch, -027£h, -013fh
dw -009fh, -004fh, -0035h, -0030h, -0027h, -0019h
dw -—0013h, -000ch, -0009h, -0004h
DataBitsTable db 0,2,4,6
5,6,7,8 bits per char frame
ParityTable db 08h,18h, 0h, 0h ; Even,Odd,Mark, Space parity
Chan0O Sr5ChannelStruct <>
Chanl Sr5ChannelStruct <>
Chan2 Sr5ChannelStruct <>
if Consumer
if Asic9
SetupTable dw offset AS5Int1l
db HwIrq2Revector,mask A9MSlave
db SelectChannel5, (mask A9MClockEnable5 shr 8)
else
SetupTable dw offset AS5Intl
db HwIrq4Revector,mask Asic2Int
db SelectChannel7, (mask ClockEnable7 shr 8)
endif
else
if Asic9
SetupTable dw offset AS5Int1l
db HwIrq4Revector,mask A9MExpIntA
db SelectChannel3, (mask A9MClockEnable3 shr 8)
dw offset AS5Int2
db HwIrq5Revector,mask A9MExpIntB
db SelectChannel4, (mask A9MClockEnable4 shr 8)
dw offset ASSInt3
db HwIrq2Revector,mask A9MSlave
db SelectChannel5, (mask A9MClockEnable5 shr 8)
else
SetupTable dw offset AS5Int1l
db HwIrq3Revector,mask ExpIntLeftA
db ExpChannelLeftA, (mask ClockEnableé shr 8)
dw offset AS5Int2
db HwIlrq2Revector,mask ExpIntRightB
db ExpChannelRightB, (mask ClockEnable5 shr 8)
dw offset AS5Int3
db HwIrq4Revector,mask Asic2Int
db SelectChannel7, (mask ClockEnable7 shr 8)
endif
endif
ProcEnd noret
Revision 1.00
Page 103 of 115 pages
The Psion SIBO Hardware Development Kit
ProcBegin@ OsAS5Install, far
Install the device driver
Out: Carry clear -happy to install
cld
mov cx, NumberOfChannels
mov di, offset Chan0od
mov si, offset SetupTable
pushf
cli
push ds
mov ax, Cs
mov ds, ax
ResetAllChannelsLoop:
mov di].Sr50pen, 0
lodsw
mov di].Sr5IntRoutineVec, ax
lodsb
mov di].Sr5IntVector, al
lodsb
mov di].Sr5Mask, al
lodsb
mov di].Sr5Channel, al
lodsb
mov di].Sr5ClockEnable, al
add di, size Sr5ChannelStruct
loop ResetAllChannelsLoop
pop ds
popft
AllChannelsOkay:
cle
ret
Mee Ne
Ne Ne Ne Ne
GotChan:
Revision
ProcEnd noret
ProcBegin@ OsAS5Remove, far
Remove the device driver
Out: Carry clear -happy to remove
~
Ne Ne Ne Ne
Psion PLC (c) May 1995
Clear the channels
and set up fixed
parameters such
as the interrupt
vectors and masks
for each channel
Channel not open
Set the interrupt
handler to call
hich Interrupt
=
Mask for that
interrupt
Which Psion serial
channel
Baud rate clocking
enable
Returns with
Carry clear
Carry set -we have an open channel and cant be removed.
xor ax, ax
or al, Chan0O.Sr50pen
or al, Chanl.Sr50pen
or al, Chan2.Sr50pen
jz AllChannelsOkay
mov ax, InUseErr
stc
ret
ProcEnd noret
ProcBegin@ OsAS5Open, far
Open a serial channel
see
In: SS:SI is a pointer to the open Ent Structure
Out: Carry clear, control block in BX
Carry set, error in AX
cld
mov si, [si] .OpenNamePtr
mov al, [sitl]
CharToFoldedChar
cmp al, 'A'
jb ErrorInOpen
sub al, 'A'
cmp al, NumberOfChannels
jae ErrorInOpen
xoOr ah, ah
mov bx, offset Chan0O
cmp al, 1
jb GotChan
mov bx, offset Chan2
ja GotChan
mov bx, offset Chanl
mov al, 1
1.00
If we have a
channel Still open
then return a can't
do error else
complete okay
Open the channel
Get the channel
Make Upper Case
Indicator which is
Part of the name
Should be A,B,C
What Channel are
We Openning
Pointer to Control
Block in bx
Page 104 of 115 pages
The Psion SIBO Hardware Development Kit
xchg al, cs: [bx].Sr50Open
cmp al, 0
je OkayToOpen
CantOpen:
mov ax, InUseErr
CantOpenDiffErr:
stc
ret
ErroriInOpen:
mov ax, NameErr
stc
ret
OkayToOpen:
xor al, al
mov cs: [bx].Sr5Running, al
mov cs: [bx].Sr5TheLines, al
mov cs: [bx].Sr5Ctrl, al
mov al, cs: [bx].Sr5Mask
HwGetChannel
jc CantOpenSoClose
call CheckHardwarePresent
jne OpenedOkay
mov al, cs: [bx].Sr5Mask
HwF reeChannel
CantOpenSoClose:
mov cs: [bx].Sr50pen, 0
mov ax, DeviceErr
jmp short CantOpenDiffErr
OpenedOkay:
xor ax, ax
ret
ProcEnd noret
AS5StrategyJumpTable label word
dw offset AS50Open
dw offset AS5Close
dw offset AS5Start
channel
dw offset AS5Stop
dw offset AS5Set
dw offset AS5Sense
dw offset AS5Control
dw offset ASS5Enquire
dw offset AS5Enable
dw offset AS5SetHandlerCs
ProcBegin@ OsAS5Strategy, far
Strategy functions entry point
Psion PLC (c) May 1995
7 Now try to Open
; That channel
; Check that we have
; The right Hardware
Return with the
Offset of our
Control Block
In bx
Ne Ne Ne Ne
; Load Handler offsets
; Close the channel
; Start the
7 Stop the channel
; Does nothing
; Returns chan status
; Drive the lines
; Returns baud rate
; Begin Output
; Get Handler segments
In: vector number in AX + various data in other registers
; Select the correct
; Output channel
Then Call the right
Function to deal
; With the strategy
7; request
; Interrupts off
;, and flags are on
; the stack
7
7 Warning! This can be called from within Interrupt
7
iH DS is OsDataGroup (and MUST be preserved)
; Out: DI is pointer to control block
H Old channel and flags on stack
cld
mov bx, sp
mov bx, ss: [bx+4]
mov bl, cs: [bx].Sr5Channel
xchg bx, ax
pushf
cli
HwSelectChannel
mov ah, bh
xOr bh, bh
push ax
mov ax, di
mov di, sp
mov di, ss: [dit+8]
jmp AS5StrategyJumpTable [bx]
ProcEnd noret
ProcBegin@ AS5Open, far
; Old channel and flags on the stack,
mov cs: [di].Sr5LddData, cx
mov word ptr cs: [di].Sr5StatusInt,
Revision 1.00
interrupts off
; Load the offsets of
ax ; the data send and
Page 105 of 115 pages
The Psion SIBO Hardware Development Kit
if
else
endif
mov word ptr cs:[di].Sr5RecvInt, si
mov word ptr cs:[di].Sr5XmitInt, dx
xor ax, ax
pop ax
HwSelectChannel
popft
ret
ProcEnd noret
ProcBegin@ AS5Close, far
Old channel and flags on the stack,
and cs:[di].Sr50Open, 0
mov al, cs: [di].Sr5Mask
HwF reeChannel
pop ax
HwSelectChannel
popft
ret
ProcEnd noret
ProcBegin@ AS5Start, far
Old channel and flags on the stack,
call CheckHardwareFromStart
mov dx, 0
je CantStartSomethingWhichIsntThere
Asic9
in ax, AQWControlExtraRW
or ah, cs: [di].Sr5ClockEnable
out A9QWControlExtraRW, ax
mov al, cs: [di].Sr5ClockEnable
HwSetA2Control2Bits
mov al, SerialWriteSingle or A5USR
SBUSY
SCONTOUT
mov al, cs: [di].Sr5Ctrl
SBUSY
SDATAOUT
mov al, SerialWriteSingle or A5BDLSB
SBUSY
SCONTOUT
mov al, byte ptr cs: [di].Sr5Baud
SBUSY
SDATAOUT
mov al, SerialWriteSingle or A5BDMSB
SBUSY
SCONTOUT
mov al, byte ptr cs: [dit+1].Sr5Baud
SBUSY
SDATAOUT
call Get TheInterrupt
xor CX), Cx
call DriveRts
mov al, SerialWriteSingle or A5CtrlReg
SBUSY
SCONTOUT
mov al, (S_CENTON or S_RS2320N or
SBUSY
SDATAOUT
mov cx, 8 ; 8 ms
pop dx
call WaitTimer
push dx
mov ah, (S_RXENB or S_TXENB or S_MDINT)
call EnableTheInterrupt
mov cs:[di].Sr5Running, 1
mov bx, Asic5SerialCurrent
HwSetPCurrent
call Status
Revision 1.00
interrupts
Psion PLC (c) May 1995
; veceive routines in
; the Ldd above us
; DX=0 —-We don't support
7; power management
; Return the old
; Channel
interrupts off
; Close the Channel
; Free up our channel
; And the Hardware
; Channel
; Return the old
; channel
off
; Start the S3s clock
; Generator
; Set the baud rate
; and other
; Characteristics
Get the interrupt
and clear down
the RTS line (DTR
stays at the state
; it was set)
S_RSTTLON)
; Switch on the line
; QGrivers and wait
; for them to power up
; Start all interrupts
Page 106 of 115 pages
The Psion SIBO Hardware Development Kit
CantStartSomethingWhichIsntThere:
pop ax
HwSelectChannel
popft
ret
ProcEnd noret
ProcBegin@ AS5Stop, far
Psion PLC (c) May 1995
; Return the old
; Channel
; Old channel and flags on the stack, interrupts off
xor CX, CX ; Clear the state of
call DriveRts ; the modem lines
mov al, SerialReadSingle or A5IntMask ; Stop all of the
SBUSY ; interrupts
SCONTOUT
XNOP
SBUSY
SDATAIN
and al, not (S_TXENB or S_RXENB or S_MDINT)
mov ah, al
mov al, SerialWriteSingle or A5IntMask
SBUSY
SCONTOUT
mov al, ah
SBUSY
SDATAOUT
pop ax
cmp dh, DevHoldPowerFail
je Dont StopHardware
cmp cs:[di].Sr5Running, 1
jne DontWait
mov cx, StopTimeOut
jmp short CompareNow
WaitForEmpty:
call TickTimer
CompareNow:
mov al, SerialReadSingle or A5USR
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
test al, S_TXEMPTY
loopne WaitForEmpty
DontWait:
cmp bh, DevHoldNormal
je Dont StopHardware
if Asic9
mov cl, cs: [di].Sr5ClockEnable ; Turn off baud rate
not cl ; Clocking from the
in ax, A9WControlExtraRW } S3y3a
and ah, cl
out A9WControlExtraRW, ax
else
mov al, cs: [di].Sr5ClockEnable
HwClearA2Control2Bits
endif
mov al, SerialWriteSingle or A5CtrlReg ; Stop the drivers
SBUSY , and stuff
SCONTOUT
sub al, al ; Clear S_CENTON,
SBUSY 7 S_RS2320N, S_RSTTLON
SDATAOUT
Dont StopHardware:
mov al, dl ; Return the old
HwSelectChannel ; Channel
popft
xor bx, bx
HwSetPCurrent
ret
ProcEnd noret
ProcBegin@ AS5Set, far
; Se SeSeees ees Sees
; Old channel and flags on the stack, interrupts off
Revision 1.00
Page 107 of 115 pages
The Psion SIBO Hardware Development Kit
; In: Information required is on the stack
pop ax
HwSelectChannel
popft
mov ah, ss:[si].SerialCharTbaud
cmp ah, ss: [si] .SerialCharRbaud
jnz ErrorInSet
cmp ah, P_BAUD_50
jb ErroriInSet
cmp ah, P_BAUD_19200
ja ErroriInSet
Got TheSpecialBaud:
dec ah
mov cl, ss:[si].SerialCharFrame
mov al, ss:[si].SerialCharParity
dec al
xor ch, ch
push bx
test cl, P_TWOSTOP
jz OnlyOneStopBit
or ch, 020h
OnlyOneStopBit:
test cl, P_PARITY
jz NoParity
mov bx, offset ParityTable
xlat cs: [ParityTable]
or ch, al
NoParity:
mov bx, offset DataBitsTable
and cl, P_DATA_FRM
mov al, cl
xlat cs: [DataBitsTable]
Or ch, al
mov bx, offset BaudRateTable
mov al, ah
xOr ah, ah
shl ax, 1
add bx, ax
mov ax, cs: [bx]
pop bx
mov es? [dt] .Sractrl; ch
mov cs:[di].Sr5Baud, ax
xOr al, al
ret
ErroriInSet:
mov al, NotSupportedErr
stc
ret
ProcEnd noret
ProcBegin@ AS5Sense, far
seo
~
Psion PLC (c) May 1995
Return the old
channel
Set the Recieve,
Transmit characteristics
First set the Baud
Rate
Then the number of
Stop bits
The Parity
And finally the
Number of data bits
Per frame
; Old channel and flags on the stack, interrupts off
; Out: The state of the DCD,CTS,DSR lines returned in DX
call Status
pop ax ; Return the old
HwSelectChannel ; Channel
popft
ret
ProcEnd noret
ProcBegin@ Status
i Out: State of modem lines in DX
mov al, SerialReadSingle or A5USR
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
and al, (S_CTS or S_DSR or S_DCD)
xor al, (S_CTS or S_DSR or S_DCD)
xOr ah, ah
Revision 1.00
see
Get the current
Modem status
Lines and return
With the result
In dx
Get the lines we want
Invert signals
Page 108 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
mov ax, ax
ret
ProcEnd noret
ProcBegin@ AS5Control, far
; Old channel and flags on the stack, interrupts off
7 In: Lines to drive and state to drive them in DX
mov onl emo ie ; Set the state of one
test dh, P_SRCTRL_DTR ; of the modem Lines
jz DriveRtsNow ; DH is the line to
call DriveDtr ; Drive and DL is the
pop ax ; Stateto drive it to
HwSelectChannel ; Return the old
popft ; channel
ret
DriveRtsNow:
call DriveRts
pop ax ; Return the old
HwSelectChannel ; channel
popft
ret
ProcEnd noret
ProcBegin@ DriveDtr
mov ah, S_DTR ; Set/Reset the DTR
jmp short DriveTheLine ; Line
ProcEnd noret
ProcBegin@ DriveRts
mov ah, S_RTS ; Set/Reset RTS
DriveTheLine:
mov al, SerialWriteSingle or A5PortD ; Common code to set
SBUSY ; and reset either
SCONTOUT ; line while
mov al, cs:[di].Sr5TheLines ; preserving the
test cl, cl ; states of the other
IZ ClearLine ; lines
or al, ah
jmp DoTheOutput
ClearLine:
not ah
and al, ah
DoTheOutput:
mov cs:[di].Sr5TheLines, al
SBUSY
SDATAOUT
ret
ProcEnd noret
ProcBegin@ AS5Enquire, far
7 Old channel and flags on the stack, interrupts off
- Out: DX,AX are the supported baud rates AX for 50 to 19200 DX for above
; CX says what data bits, parity, etc we support
pop ax ; Return the old
HwSelectChannel ; Channel
popf
if Asic9
mov ax, —-1
else
mov ax, O7fffh
endif
xor dx, ax
mov cx, (Offffh AND (NOT (P_SRINQ_SPLIT OR P_SRINQ_PARSPACE OR
P_SRINQ_PARMARK) ) )
ret
ProcEnd noret
ProcBegin@ AS5Enable, far
Revision 1.00 Page 109 of 115 pages
The Psion SIBO Hardware Development Kit
Psion PLC (c) May 1995
- Old channel and flags on the stack, interrupts off
mov ah, S_TXENB ; Begin Output by
call EnableTheInterrupt ; enabling transmit
pop ax ; interrupts
HwSelectChannel ; Return the old
popft ; channel
ret
ProcEnd noret
ProcBegin@ AS5SetHandlerCs, far
CX is CS of above LDD
sew
mov word ptr cs: [di]. (Sr5StatusInt+2), cx
mov word ptr cs:[di].(Sr5RecvInt+2), cx
mov word ptr cs: [di]. (Sr5XmitInt+2), cx
pop ax
HwSelectChannel
popft
ret
ProcEnd noret
ProcBegin@ AS5Int3, far
mov di, offset Chan2
mov ax, PortCActive
jmp ComInt
ProcEnd noret
ProcBegin@ AS5Int2,far
mov di, offset Chanl
mov ax, PortBActive
jmp ComIint
ProcEnd noret
ProcBegin@ AS5Int1,far
mov di,offset Chan0
mov ax, PortAActive
4 FALL THROUGH
ProcEnd noret
ProcBegin@ ComInt, far
The common interrupt handler
DS points to OS data space
DI is our control block
Mee Ne
; AX is the Active channel
ab S3b or S3c
or ds: [OsActivityMeter], ax
endif
mov al, cs: [di].Sr5Channel
HwSelectChannel
push ax
mov bx, cs: [di].Sr5LddData
TheInterruptLoop:
mov al, SerialReadSingle or A5CtrlReg
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
test al, al
je NothingToDo
HaveWeGotAModemStatusLineInterrupt:
test al, S_MDINT
4z HaveWeGotARecievelInterrupt
mov al, SerialReadSingle or A5USR
SBUSY
SCONTOUT
Revision 1.00
~
Mee Ne
Old channel and flags on the stack, interrupts off
; Load the Segment
; Within which the
The Ldd above us
Return the old
channel
; Resides
Channel 3 interrupt
vector
Jumps to Comint
see
~
Channel 2 interrupt
vector
Jumps to Comint
seo
~
Channel 1 interrupt
7; vector
; Falls through
7 to Comint
; Set active state
; Select our
; Channel
; Data for LDD above
; in bx
; Find out what
; caused the
; interrupt
Page 110 of 115 pages
The Psion SIBO Hardware Development Kit
Psion PLC (c) May 1995
; Something has been
; recieved in error
; Establish the error
; Get the character
; in question
; invert signals
XNOP
SBUSY
SDATAIN
test al, (OVERRUN_ERROR or PARITY_ERROR)
jz ModemStatusInterruptOnly
push ax
mov ah, SERPARITY_ERR
test al, PARITY_ERROR
jnz IsAParityError
mov ah, SEROVERRUN_ERR
IsAParityError:
mov al, SerialReadSingle or A5RHR
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
push di
call dword ptr cs: [di] .Sr5RecvInt
pop di
pop ax
ModemStatusInterruptOnly:
and ax, (S_CTS or S_DSR or S_DCD)
xor al, (S_CTS or S_DSR or S_DCD)
mov ax, ax
push di
call dword ptr cs: [di].Sr5StatusInt
pop di
jmp short TheInterruptLoop
HaveWeGotARecievelInterrupt:
; AX has character received
Resced if neccessary
; Gisable TX interrupts
test al, S_RXINT
jz HaveWeGotATransmitInterrupt
mov al, SerialReadSingle or A5RHR
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
xOr ah, ah
push di
call dword ptr cs: [di] .Sr5RecvInt
pop di
jmp short TheInterruptLoop
HaveWeGotATransmitInterrupt:
test al, S_TXINT
jz NothingToDo
push di
call dword ptr cs: [di] .Sr5XmitInt
pop di
test ax, ax ; —-l1 if disable
js DisableTransmitInts
mov ah, al
mov al, SerialWriteSingle or A5RHR
SBUSY
SCONTOUT
mov al, ah
SBUSY
SDATAOUT
jmp TheInterrupt Loop
NothingToDo:
if Asic9
out A9BNonSpecificEoiwW, al
else
out AlNonSpecificEoi, al
endif
pop ax
HwSelectChannel
cle ;
ret
DisableTransmitInts:
mov al, SerialReadSingle or A5IntMask
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
and al, not S_TXENB
mov ah, al
mov al, SerialWriteSingle or A5IntMask
SBUSY
Revision 1.00
Page 111 of 115 pages
The Psion SIBO Hardware Development Kit
SCONTOUT
mov
SBUSY
SDATAOUT
jmp TheInterrupt Loop
ProcEnd noret
al, ah
ProcBegin@ GetTheInterrupt
mov al, cs:[di].Sr5IntVector H
mov Cx, CS F
mov bx, cs:[di].Sr5IntRoutineVec ;
GenSetRevector A
ret ,
ProcEnd noret
ProcBegin@ EnableTheInterrupt
mov al, SerialReadSingle or A5IntMask
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
or ah, al
mov al, SerialWriteSingle or A5IntMask
SBUSY
SCONTOUT
mov al, ah
SBUSY
SDATAOUT
if Asic9
in al, A9BInterruptMaskRW ;
or al, cs: [di].Sr5Mask ;
out A9BInterruptMaskRwW, al
else
in al, AlInterruptMask
or al, cs: [di] .Sr5Mask
out AlInterruptMask, al
endif
ret
ProcEnd noret
ProcBegin@ StopInterrupts
; StessSeSesee—e-Seeeseeese
mov al, SerialReadSingle or A5IntMask H
SBUSY ;
SCONTOUT
XNOP
SBUSY
SDATAIN
and al, not (S_RXENB or S_TXENB or S_MDINT)
mov ah, al
mov al, SerialWriteSingle or A5IntMask
SBUSY
SCONTOUT
mov al, ah
SBUSY
SDATAOUT
mov ah, cs: [di].Sr5Mask
not ah
if Asic9
in al, A9BInterruptMaskRW ;
and al,ah ;
out A9BInterruptMaskRW, al ;
else ;
in al, AlInterruptMask
and al,ah
out AlInterruptMask, al
endif
mov al, cs:[di].Sr5IntVector
GenResetRevector
ret
Revision 1.00
Psion PLC (c) May 1995
Load the address of
the appropriate
interrupt routine
into the correct
vector
Set the mask
to enable Interrupts
Stop interrupts
from Asic5
Stop Interrupts
By clearing the
Mask and resetting
The Vector
Page 112 of 115 pages
The Psion SIBO Hardware Development Kit
ProcEnd noret
ProcBegin@ CheckHardwarePresent
mov al, cs: [bx] .Sr5Channel
HwSelectChannel
HwNullFrame
mov al, (SerialSelect or Asic5Normalld)
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
test al,al
je ConnectionFailed
GotConnection:
popft
ous)
ret
ConnectionFailed:
mov al,
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
test
jne
mov
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
test
jne
mov
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
ConnectionFailedExit:
popft
stc
ret
ProcEnd noret
SerialSelect or Asic4Id
al, al
ConnectionFailedExit
al, SerialSelect or Asic8Id
al, al
ConnectionFailedExit
al, SerialSelect or Asic5PackId
ProcBegin@ CheckHardwareFromStart
pushf
HwNullFrame
mov al, (SerialSelect or Asic5Normalld)
SBUSY
SCONTOUT
XNOP
SBUSY
SDATAIN
test al,al
je ConnectionFailed
test al, mask A5MultiDrop
jne ConnectionFailedExit
popft
mov
SBUSY
SCONTOUT
mov
SBUSY
SDATAOUT
cle
ret
ProcEnd noret
al,
al, S_PERIPHERALMODE
ProcBegin@ WaitTimer
Revision 1.00
SerialWriteSingle or A5PortBMode
Ne Ne Ne Ne te
Ne Ne Ne Ne Ne
Psion PLC (c) May 1995
Check that the
; Harware is there
And that it is what
It should be
First look for An
ASIC4 at the other
End of the link
Asic4 Id
Modem chip Id
Asic5Spack Id
Check that the
Harware is there
First look for An
ASIC5 at the other
End of the link
If not a 3link or
if in multidrop
mode then we are
in trouble
Put the 3Link in
peripheral mode
Page 113 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
In: CX number of ms to wait for
Channel store in DL
Out: Channel store in DL
Wait for a given
inc cx i
WaitTickLoop: ; Number of ms
call TickTimer ; Plus one to guarantee
loop WaitTickLoop ; That at least cx ms
ret 7 Go by
ProcEnd
WaiterLoop:
stack
stack
ProcBegin@ TickTimer
Uses writes down our channel to simulate tick timer waits
Must allow interrupts so other things can run -we will be here
for 1/1000 of a second and may be called many times
ChannelStore in/out in DL
mov al, dl ; Return the old
HwSelectChannel ; Channel
mov ah, al
pushf
sez
push Cx
mov cx, 12 ims
128 frames =1lms
pushf about 12 times
cli 7 round the loop
out ResetWatchDog, al
mov al, ah
HwSelectChannel
mov dl, al ; Get Correct channel
mov al, (SerialWriteSingle or 0) Do a write to
SBUSY nowhere and
SCONTOUT waste some time
See Ne
See Ne
SCONTOUT ; Do it eight times
SBUSY
SCONTOUT
SBUSY
mov al, dl
HwSelectChannel
mov ah, al
popft
loop WaiterLoop
pop CX
popft
mov al, ah
HwSelectChannel
mov dl, al
ret
ProcEnd
Return the old
channel
EndCodeSeg
segment stack para 'data'
ends
end OsAS5PDD
Revision 1.00 Page 114 of 115 pages
The Psion SIBO Hardware Development Kit Psion PLC (c) May 1995
Assembler Macros
Excerpts from the include file ossibo.inc.
if ASIC1
SCONTOUT macro
out A2SerialControl, al
endm
SDATAOUT macro
out A2SerialData, al
endm
SBUSY macro
wait
endm
SREAD macro _REG
mov al, SerialReadSingle or _REG
out A2SerialControl, al
nop
SBUSY
in al, A2SerialData
endm
SREADM macro _REG
mov al, SerialReadMulti or _REG
out A2SerialControl, al
nop
SBUSY
in al, A2SerialData
endm
SWRITE macro _REG,_VAL
mov al, SerialWriteSingle or _REG
out A2SerialControl, al
SBUSY
mov al, _VAL
out A2SerialData, al
endm
SWRITEM macro _REG,_VAL
mov al, SerialWriteMulti, _REG
out A2SerialControl, al
SBUSY
mov al, _VAL
out A2SerialData, al
endm
endif
ach ASIC9
SCONTOUT macro
out A9BSerialControlW, al
endm
SDATAOUT macro
out A9BSerialDataRW, al
endm
SDATAIN macro
in al, A9BSerialDataRW
endm
SBUSY macro
endm
SREAD macro _REG
mov al, SerialReadSingle or _REG
out A9BSerialControlwW, al
in al, A9BSerialDataRW
endm
SREADM macro _REG
mov al, SerialReadMulti or _REG
out A9BSerialControlwW, al
in al, A9BSerialDataRW
endm
SWRITE macro _REG,_VAL
mov al, SerialWriteSingle or _REG
out A9BSerialControlwW, al
mov al, _VAL
out A9BSerialDataRW, al
endm
SWRITEM macro _REG,_VAL
mov al, SerialWriteMulti or _REG
out A9BSerialControlwW, al
mov al, _VAL
out A9BSerialDataRW, al
endm
endif
Revision 1.00 Page 115 of 115 pages