RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

Expansion card support


Introduction and Overview

The expansion card interface has been enhanced in several ways for RISC OS 3.5. It now supports:

  • 32 bit wide data paths
  • a directly mapped area of 16MB per card, known as EASI space
  • an interface dedicated to a network card
  • Direct Memory Addressing (DMA).

This chapter covers the changes that have been made in order to support these enhancements; all these changes apply from RISC OS 3.5onwards.

Technical details

Using EASI space

EASI space is an extension of the existing space giving a directly mapped area of 16MB for each expansion card. The address of this space is set in the RISC OS ROM.

ROMs in EASI space

The expansion card bus is electrically capable of having ROMs (or EPROMs) connected, which RISC OS can then read. The ROMs are only 8 bits wide and are copied once at start up into RAM.

Under earlier versions of RISC OS, this was always done using a loader and paging register. However, from RISC OS 3.5 onwards there is no need for this if a ROM is mapped into EASI space, since RISC OS does the loading itself. Mapping a ROM into EASI space has other advantages: access to the entire ROM address space is faster, and not having loaders frees-up ROM space.

The format for a ROM in EASI space is the same as that for a ROM in the normal expansion card space; it must contain the same ECId information. However, since the size restriction is lifted there is no need to have a second Chunk directory accessed through the loader. Note that although the ROM is in the EASI space, the interrupt relocations are still relative to the base of expansion card space.

Determining where a ROM is to be loaded

RISC OS will cope with a ROM in only one of expansion card space and EASI space, not both at once. When determining which is present, it first checks for a ROM in expansion card space by reading location 0. If bit 1 is low it assumes there is a ROM in expansion card space, and does not access EASI space.

If you wish to use a ROM in EASI space, it is vital that your expansion card either does not respond to reads of location 0, or provides data with bit 1 set high. Failure to do this will make RISC OS read spurious data as it attempts to load a non-existent ROM from expansion card space, and ignores the ROM in EASI space.

It also follows that you must not map read-sensitive hardware into location 0, or its state may be altered as RISC OS attempts to load ROMs at boot time.

Finding EASI space

You can read the logical and physical addresses of the area and its size by calling Podule_ReadInfo. The returned addresses are stable as long as the machine configuration is stable, and therefore only need be read once, after a reset.

The network card

ROMs on the network card

RISC OS 3.5 - and later versions - loads the ROM on a network card itself, in a similar manner to ROMs mapped into EASI space. For this loader to work, it is vital that your network card conforms to the current hardware specification.

The format for a ROM on a network card is also the same as that for a ROM in the normal expansion card space. It must contain the same ECId information; the interrupt relocations must be present and all be set to zero. Since the loader is effectively loaded before the enumeration begins, there is again no need to have a second Chunk directory.

SWIs and the network card

Most SWIs work with the network card, simply by quoting its ROM section when calling (see ROM sections). You should note the following:

ROM sections

New ROM section numbers

ROM section numbers have been allocated for a further four expansion cards, and for the network card. The network card is the highest numbered one, and is last in the printout from *Podules.

The new numbers are:

ROM section Meaning
4 Expansion card 4
5 Expansion card 5
6 Expansion card 6
7 Expansion card 7
8 Network card
New ways of specifying the ROM section

All expansion card SWIs (with the single exception of Podule_ReturnNumber) use R3 to specify which expansion card or extension ROM to access. Some calls can access both, and are documented as accepting a ROM section number; others can access only expansion cards, and are documented as accepting an expansion card slot number (ie a subset of ROM sections).

As well as ROM section numbers, these SWIs now also accept a hardware base address (as returned by Podule_HardwareAddress or Podule_HardwareAddress), whether or not it is combined with a CMOS address.

The 'formal definition' of what is acceptable in R3 is as follows (demonstrated by the following pseudo code):

CASE
WHEN Value = -1: System ROM ==> Error "System ROM not acceptable as
                                Expansion Card or Extension ROM number"
WHEN Value <= -2 AND >= -16: Extension ROM(-Value-1)
WHEN Value >= 0 AND <= 31: Expansion Card(Value)
WHEN Value AND &FFE73000 = &03240000: Expansion Card((Value AND &C000)>>14)
WHEN Value AND &FFE73000 = &03270000: Expansion Card(4+(Value AND &C000)>>14)
WHEN Value AND &FFFF3FFF = &03000000: Expansion Card((Value AND &C000)>>14)
WHEN Value AND &FFFF3FFF = &03030000: Expansion Card(4+(Value AND &C000)>>14)
WHEN Value >= &70 AND <=&7F: Expansion Card((Value AND &C)>>2)
WHEN Value >= &3C AND <=&4F: Expansion Card(7-((Value AND &C)>>2))
WHEN Value = EASILogicalBase(0..7): Expansion Card(0..7)
WHEN Value = EASIPhysicalBase(0..7): Expansion Card(0..7)
OTHERWISE Error "Bad Expansion Card or Extension ROM number"
ENDCASE

Changes to the combined hardware address

The definition of the combined hardware address has had to be changed to allow for the introduction both of the network card and of processors with 32 bit addressing.

The combined hardware address consists of the base address of CMOS RAM and the base address of an expansion card or extension ROM, OR'd together. The bits that are set in one address can be guaranteed unused in the other, because the two addresses are so widely separated. By using two different masks, the two addresses can be extracted.

In earlier versions of RISC OS:

  • All expansion cards had a base address above &1000, and so the lower 12 bits of the combined address were used for the CMOS base address.
  • The processor used 26 bit addressing, so the top 6 bits of the combined address were unused

However, under RISC OS 3.5 and later:

  • The network card has a base address below &1000, and so now only the lower 10 bits of the combined address are used for the CMOS base address (which is still sufficient).
  • The processor supports 32 bit addressing, so the combined address now uses all 32 bits.

The new definition is thus:

Bits Meaning
0 - 9 base address of CMOS RAM - expansion cards only (10 bits)
12 - 32 bits 12 - 32 of base address of expansion card/extension ROM

All this has really done is to move the boundary between the two parts of the combined address. Existing expansion cards and extension ROMs will continue to work, because their base address under RISC OS 3.5 will still only have bits 12 - 25 set, as before.

These changes apply both to SWIs returning combined hardware addresses, and to the entry points for loaders. Entry points in new expansion cards should now extract the hardware base address by masking the incoming register value thus:

LDR Rmv, =2_00000000000000000000001111111111
BIC Rba, Rha, Rmv

or thus:

LDR Rmv, =2_11111111111111111111110000000000
AND Rba, Rha, Rmv

and should obtain the CMOS base address thus:

LDR Rmv, =2_11111111111111111111110000000000
BIC Rca, Rha, Rmv

or thus:

LDR Rmv, =2_00000000000000000000001111111111
AND Rca, Rha, Rmv

Simple expansion card descriptions

Some expansion cards use only a simple ECId, where the product is identified by a 4 bit ID field unique to that product. However, there is no way of providing a textual description of the product. Support for this has been added from RISC OS 3.5 onwards.

The description is held in the file:

Resources:$.Resources.Podule.Messages

It is looked up as a token consisting of the string Simple followed by a single hexadecimal digit giving the ID field (which must be 1 - F). For example, the line that is looked up for an ID field of 1 is:

Simple1:Acorn Econet

This method is used to extend *Podules (to return a description of simple expansion cards. The description can also be read using Podule_ReadInfo.

New chunk type for device data

A new chunk type has been defined for device data (see Operating System Identity Byte). The value 9 indicates a two byte chunk used to store a CRC of the ROM, typically only used by proprietary diagnostic and test software.

SWI calls


Podule_ReadInfo
(SWI &4028D)

This call returns a selection of data specific to a given expansion card

On entry

R0 = bitmask of required results (see below)
R1 = pointer to buffer to receive word aligned word results
R2 = length in bytes of buffer
R3 = ROM section (see ROM sections and ROM sections)

On exit

R0, R1 preserved
R2 = length of results
R3 preserved

Interrupts

Interrupt status is unaltered
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call returns a selection of data specific to the given expansion card. The information required is specified by bit flags. The data is returned in single words, which are placed into the user supplied buffer at word intervals, in the same order as the bit flags (ie data for the lowest bit set is at the lowest address).

The bit flags are:

Bit Value to return when set
0 Expansion card/Extension ROM number
1 Normal (synchronous) base address of hardware
2 CMOS address
3 CMOS size in bytes
4 Extension ROM or network ROM base address
5 Expansion card ID
6 Expansion card product type
7 Combined hardware address
8 Pointer to description (zero for no description)
9 Address of EASI space
10 Size of the EASI space in bytes
11 Logical number of the primary DMA channel
12 Logical number of the secondary DMA channel
13 Address of Interrupt Status Register
14 Address of Interrupt Request Register
15 Address of Interrupt Mask Register
16 Interrupt Mask value
17 Device Vector number (for IRQ)
18 Address of FIQ as Interrupt Status Register
19 Address of FIQ as Interrupt Request Register
20 Address of FIQ as Interrupt Mask Register
21 FIQ as Interrupt Mask value
22 Device Vector number (for FIQ as IRQ)
23 Address of Fast Interrupt Status Register
24 Address of Fast Interrupt Request Register
25 Address of Fast Interrupt Mask Register
26 Fast Interrupt Mask value
27 Ethernet address (low 32 bits)
28 Ethernet address (high 16 bits)
29 Address of MEMC space (zero for no space)
30 - 31 Reserved (must be zero) - error if set

The description strings may be in temporary buffers (for example, MessageTrans error buffers) so it is wise to copy them to private workspace before calling any other SWIs.

When updating any of the nine interrupt registers it is essential that both IRQ and FIQ are disabled for the duration.

This SWI supersedes other expansion card SWIs such as Podule_HardwareAddress.

This call is only available from RISC OS 3.5 onwards.

Related SWIs

Podule_ReadID, Podule_ReadHeader, Podule_HardwareAddress, Podule_HardwareAddresses, Podule_ReturnNumber

Related vectors

None


Podule_SetSpeed
(SWI &4028E)

Changes the speed of access to expansion card hardware

On entry

R0 = new speed required:

0 => No change
1 => IOMD+ timing type A
2 => IOMD+ timing type B
3 => IOMD+ timing type C
4 => IOMD+ timing type D

R3 = ROM section (see ROM sections and ROM sections)

On exit

R0 = previous speed setting
R3 preserved

Interrupts

Interrupt status is unaltered
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call changes the speed of access to expansion card hardware. The kernel initialises all expansion cards' access speed to type A.

This call is only available from RISC OS 3.5 onwards.

Related SWIs

None

Related vectors

None

Application Notes

Reading the machine supplied value for the Ethernet address should ideally be carried out using the following code. Note that this is not the only way to get the required result, but it is the recommended way:

GetEthernetAddress
; Entry;
;       R3 ==> Any recognisable part of podule addressing
;
; Exit;
;       R0 ==> Low 32 bits of the Ethernet address
;       R1 ==> High 16 bits of the Ethernet address
        STMFD   r13!, {r0-r2, r4, r14}
        MOV     r0, &18000000           ; Bits for read high and low
        MOV     r1, r13                 ; Point to the buffer
        MOV     r2, #8                  ; Size of buffer
        SWI     XPodule_ReadInfo
        LDMVCFD r13!, {r0-r2, r4, pc}   ; Return with results if OK
        MOV     r4, r0                  ; Save the original error
        MOV     r0, #0                  ; Start at the first chunk
Loop
        SWI     XPodule_EnumerateChunks
        BVS     ErrorExit
        TEQ     r0, #0
        BEQ     ErrorExit               ; End of list, so not found
        TEQ     r2, #&F7                ; Ethernet Address?
        BNE     Loop
        TEQ     r1, #6                  ; Wrong size is a failure
        BNE     ErrorExit
        SUB     r0, r0, #1              ; Back to the chunk we liked
        MOV     r2, r13                 ; Pass in the data pointer
        SWI     XPodule_ReadChunk
        LDMVCFD r13!, {r0-r2, r4, pc}   ; Return with results if OK
ErrorExit
        CMP     pc, #&80000000          ; Set V
        STR     r4, [r13, #0]           ; Original error Podule_ReadInfo
        LDMFD   r13!, {r0-r2, r4, pc}

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015