. > <wini>arm.IO_Podule.Document

  The current BBC I/O podule software comprises the following items:

1)     BBCIOBoardLoader         an Arthur loader
2)     I/O_Podule               an Arthur relocatable module

  The loader provides the Arthur OS with the ability to read bytes out of the
paged EPROM, and to reset the hardware to an appropriate state when a
PreReset arrives. The loader is loaded by the Podule manager when the OS
first tries to enumerate the contents of the podule (normally after a hard
break).

  The relocatable module is normally downloaded from the podule by Arthur. In
this case, it is given the hardware address at module initialisation. It may
also be RMLoaded separately and in this case reads the podule slot number
from the command tail, eg. *RMLoad $.rm.IO_Podule 2. The module will refuse
to initialise if no hardware address is given by either method. It provides:

a SWI, "XI/O_Podule_Hardware",  &40500 :OR: X_bit

In:     none

Out:    VSet:
          r0 -> error block (probably because module not present)
        VClear:
          r1 -> SYNC (ie. 2MHz access) base of I/O podule
          For offsets within the podule, see the I/O podule User Guide
          To offset from this to the MEMC podule space, subtract &00200000

several unknown OS_Bytes: (ref. BBC Advanced User Guide, Bray et al.)

ADC OS_Bytes
============

In:     r0b = 16
        r1b = number of channels to convert on

Out:    r1  = old number of channels was converting on
        r2 undefined

  If r1b is not zero, then a conversion is started on r1b. ADCMaximumChannel
(OS_Byte 189 variable) is read and then updated by this call. No check is
done at this stage to see if this is valid. Note that when writing this value
to zero, conversions will only stop after channel 1 has converted again. In
this document channel refers to the logical channel number, ie. 1..4 that the
user will use, not the physical channel number used by the ADC.

  Starting a conversion first checks that the channel number is not zero;
this is a NOP. Channel numbers > 4 are mapped to 4, and this new value stored
in ADCCurrentChannel (OS_Byte 188 variable). The ADC is then instructed to
start a conversion of the appropriate type as governed by ADCConversionType
(OS_Byte 190 variable), either 8 bit or 12 bit. Note that all non-8 values
result in 12 bit conversions.

In:     r0b = 17
        r1b = channel to force conversion on

Out:    r1, r2 undefined

  A conversion is started on the given channel (see above description). The
last converted channel number is set to zero.

In:     r0b = 128 (ADVAL)
        r1b = 0

Out:    r1  = fire button state b[1:0], ~LPSTB b[2] (to make this input useful)
        r2  = last channel number to have completed conversion
              (0 -> no channel has yet completed conversion)

In:     r0b = 128 (ADVAL)
        r1b = 1..4 channel to read last converted value for

Out:    r1  = LSB of value last converted on channel r1b
        r2  = MSB of value last converted on channel r1b (NB. NOT sign extended)

  If the given channel has not yet converted, the result is undefined. To
obtain a signed integer from this call use:

        SWI     XOS_Byte
        MOV     r2, r2, LSL #16
        ORR     r1, r1, r2, ASR #16

  On module initialisation, the conversion process is started with
ADCMaximumChannel = 4 and the last converted channel = 0. On a reset
service, the current conversion process is restarted, unless
ADCMaximumChannel is zero.

  On module death, the software disables interrupts, starts a conversion on
channel 1 (physical channel 0) and waits for it to complete, before restoring
the interrupt state and dying, as this is the only way of disabling the ADC.

  On an ADC conversion, the converted values are read from the ADC and stored
in a table indexed by the channel number that converted ie. ADCCurrentChannel
reduced into 1..4 (0 and > 4 -> 4). The last converted channel is set to the
converted channel number and an event is raised:

       r0 = Event_ADCConvert (3)
       r1 = channel number that just converted

  When this returns, a conversion is started on the next lowest channel, or
on ADCMaximumChannel if the last conversion was on channel 1. At this point,
if ADCMaximumChannel is zero the conversion process stops and may be
restarted by OS_Bytes 16 or 17. Merely writing ADCMaximumChannel or
ADCCurrentChannel will NOT restart the conversion process.

  The aforementioned OS_Byte variables (188..190) are stored in the main
OSByteVars area and may all be modified using the standard read/write
OSByteVars calls. Note that no error will be given if the I/O podule software
is not present.

BBC I/O area read/write OS_Bytes
================================

In:     r0b = &92
        r1b = offset in area FRED

Out:    r2  = byte read from FRED+r1b

In:     r0b = &93
        r1b = offset in area FRED
        r2b = byte to write at FRED+r1b

Out:


In:     r0b = &94
        r1b = offset in area JIM

Out:    r2  = byte read from JIM+r1b

In:     r0b = &95
        r1b = offset in area JIM
        r2b = byte to write at JIM+r1b

Out:


In:     r0b = &96
        r1b = offset in area SHEILA (see below)

Out:    r2  = byte read from SHEILA+r1b

In:     r0b = &97
        r1b = offset in area SHEILA (see below)
        r2b = byte to write to SHEILA+r1b

Out:

  Only offsets corresponding to the USER VIA (&60..&6F and the ghost at
&70..&7F) and ADC (&C0..&C2 and ghosts &C4..&C6, &C8..&CA, &CC..&CE,
&D0..&D2, &D4..&D6, &D8..&DA, &DC..&DE) are trapped on the read/write SHEILA
calls; other offsets are passed on.

  The User VIA calls also pass on accesses to IRA/ORA/DDRA/IRA_NH/ORA_NH as
port A is the printer port on the BBC, and is used for paging the EPROM and
for fire button & LPSTB inputs on this podule. Writes to the PCR ensure that
CA2 is kept as an active low output thus keeping IRQs from the I/O podule
enabled.

  The ADC calls should really be used with care as they will interfere with
the ADC handling provided by this module, just as on a real BBC!

  On module initialisation and on a reset service, the User VIA is set up so
that CA2 has a low output to enable IRQ from this podule and CA1,CB1,CB2 are
negative active edge IRQ sources. All pending interrupts are cleared from the
IFR and the IER completely disabled. Note that the CA2 state MUST be
preserved by any user program directly modifying the PCR. Port B, the ACR and
the timers are all undefined.

*end*
