Commit 2575b028 authored by Neil Turton's avatar Neil Turton
Browse files

Import from cleaned 360 CD

hdr/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true
s/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true
SWI Interface for Joystick Devices
==================================
The Joystick module provides a SWI interface for reading the state
of a joystick. When the module initialises it tests for the existance
of built-in joystick hardware and if it does not find any then it will
not initialise. Third parties can replace this module to provide
different hardware. It is recommended that any such modules have
version numbers greater than 2.00 so that Acorn can upgrade its own
module without preventing its replacement.
Joystick_Read (SWI &43f40)
Returns the state of a joystick.
On entry: R0 = joystick number
On exit: R0 = joystick state
Interrupts: Interrupt status is not altered
Processor mode: Processor is in SVC mode
Re-entrancy: Not defined
Use: This SWI is used to obtain the state of the requested
joystick. The state is returned in the following
format:
Byte 0: signed Y value (range -127 to 127)
-64, 0 or 64 for single switch joystick
(corresponds to Down, Rest, Up).
Byte 1: signed X value (range -127 to 127)
-64, 0 or 64 for single switch joystick
(corresponds to Left, Rest, Right).
Byte 2: Switches (eg. fire buttons) starting in
bit 0, unimplemented switches return 0.
Byte 3: Reserved.
Note that this format allows both digital and analogue
devices to be supported. Applications which are only
interested in state (up, down, left, right) should not
simply test the bytes for positive, negative or zero.
It is recommended that the at rest state should span a
middle range, say from -32 to 32 since analogue joysticks
cannot be relied upon to produce 0 when at rest.
Related SWIs: None
Related vectors:None
Joystick Device Driver
======================
Steve Cormie (6 Nov 1991), Revision 0.01
----------------------------------------
Requirements
------------
1) The state of a joystick should be polled by a SWI call.
2) Must provide a consistent interface.
3) Software which requires the use of joysticks should not have to be modified
in order to work on machines which have no built-in joystick ports but have
been fitted with a podule and driving software from an ISV.
4) It should also be possible for ISVs to add extra joysticks to a product
which already has built-in joystick ports (ideally the same podule and
driving software described in 2).
5) There must be clear guidelines for ISVs who wish to produce drivers which
adhere to the joystick interface.
6) Should be sufficiently fast.
7) Should it be possible to use the interface which will be defined on
RISC OS 2 machines? - Could be very important to games developers.
Hardware
--------
It would be nice to be able to determine if the joystick hardware existed or
not. This has not been implemented in hardware terms but the scheme which has
been proposed is as follows:
- write &FF to a joystick port magic address
- read back from the same address
- if bit 0 of the byte read back is 0 then
the hardware is present (bit 0 pulled low)
else
the hardware is not present (bus is pulled high)
The hardware latches the current state of a joystick AFTER a byte is read from
the magic address (this is to avoid reading while the lines are in a transient
state). This means that the magic address must be read twice in order to get
the current state of a joystick, once to latch in the current state and then
again to read it.
The state byte which is returned has the following format:
bits 7-0: XXXFRLDU
Where X - undefined
U - Up
D - Down
L - Left
R - Right
F - Fire
Possible Interfaces to Joystick Device Driver
---------------------------------------------
There are three possible methods for implementing the joystick device driver.
These are described below with the advantages and disadvantages of each.
Simple SWI Interface
--------------------
This is the most simple approach where only an interface to the built-in joystick
ports is provided. A module called Joystick would be written which would provide
the following SWI:
SWI Joystick_Read
In: joystick number
Out: joystick state
On initialisation the module would test for the presence of the hardware and if
it was not there then the module would not initialise. This allows ISVs to test
for the existance of built-in joysticks using RMEnsure and to load their own
driver if required.
Advantages:
a) Satisfies requirements 1.
b) Provides a consistent interface. Software which uses joysticks simply calls
the SWI (satisfies requirement 2).
c) ISVs can provide a module which replaces this SWI with one which will read
the state of its own joystick devices (satisfies requirement 3).
d) Simple interface for ISVs to implement when writing their own joystick
drivers (satisfies requirement 5).
e) Very fast (satisfies requirement 6).
f) Backwards compatible with RISC OS 2. The same software can be run on RISC OS 2
machines by loading a module which provides the Joystick_Read SWI (satisfies
requirement 7).
g) Defines a standard interface which can be applied to RISC OS 2 and 3.
h) Quick and easy implementation (more time to do other work).
i) Small amount of additional documentation (one SWI).
j) Module would be very small (don't want to use too much ROM space).
Disadvantages:
a) It is not easy to satisfy requirement 4 ie. adding joysticks to a product
which has built-in joystick ports. ISV joystick drivers would replace the
SWIs, effectively disabling the built-in joystick ports. Device drivers
which add extra joysticks would have to be different to those which merely
provide the Joystick_Read SWI. It could be argued that all we have to do
is provide the primitive interface to the built-in joystick ports, any
other issues such as extra joysticks can be handled by ISVs. This means
that software which uses more than two joysticks would have a different
interface.
Vectored Interface
------------------
A new vector called PollV could be introduced. Device drivers which handle
devices which can be polled hang a handler routine off this vector using OS_Claim.
The routines which are hung off this vector take the following parameters:
device (eg. Joystick, UserPort etc.)
device specific data
A module called Joystick would be written which would hang a joystick device
driver off PollV (only if the hardware is present). The input to this routine
would be as follows:
device (must be Joystick)
joystick number
It's action would be:
if device is not Joystick or joystick number > 1 then
pass the call on to another handler
else
return the joystick state
ISV joystick device drivers could also hang handlers off PollV. These routines
would respond to requests for joysticks 0 and 1 on machines with no built-in
joystick ports or could respond to requests for higher numbers for extra
joysticks and pass on requests for joysticks 0 and 1 to the above handler.
A SWI would be written which would poll a specified device ie:
SWI OS_Poll
In: device (eg. Joystick)
device specific data
Out: state of device
This SWI would initiate a call which is passed down the list of handlers hanging
off PollV until one of them claims the call and responds with the state of its
device. This SWI would be used to poll a joystick.
Advantages:
a) Requirement 1 is satisfied.
b) Provides a consistent interface. Software which uses joysticks would
simply call OS_Poll with the joystick number (satisfies requirement 2).
b) The OS_Poll SWI is all that software which uses joysticks need to get the
state of built-in or extra joysticks. ISV joystick device drivers would
hang their handler off PollV and only respond to requests for the state
of their joysticks. This means that the Joystick module handler and the
ISV handler can co-exist hence requirements 3 and 4 are met.
c) Satisfies requirement 6.
d) This mechanism will support any device which can be polled eg. external
switches etc. all that changes is the device number and device specific
data which is passed through OS_Poll.
Disadvantages:
a) There would be much more documentation required for this interface, the new
vector and its uses, the OS_Poll SWI etc.
b) This would not be backwards compatible with RISC OS 2 (there is no PollV or
OS_Poll SWI).
To allow backwards compatibility SWI Joystick_Read could be added to the
Joystick module. This would call OS_Poll and some handler (possibly in
an ISV driver) would return a state which Joystick_Read would then
return. On RISC OS 2 all that would be required is a module which
provides the Joystick_Read SWI (however, this effectively reduces the
interface back to the Joystick_Read SWI and all we have gained is the
extra vector and the facility for ISVs to install extra joysticks).
Using DeviceFS
--------------
It could be argued that the correct approach for RISC OS 3 is to use DeviceFS.
A device would be created for each joystick eg. Devices:$.Joystick.0,
Devices:$.Joystick.1 etc. To read the state of a joystick the software would
open the device using OS_Find and then read from it using OS_BGet until the
software terminates (at which point it must close the device).
Joystick device drivers provided by ISVs could then create their own devices
eg. Devices:$.Joystick.2 (as an extra joystick) or provide joystick devices
0 and 1 on machines which have no built-in joystick ports.
Advantages:
a) The state of a joystick can be polled by a SWI call (read the state using
OS_BGet from the required joystick device, this satisfies requirement 1).
b) The DeviceFS module provides a standardised interface to device drivers
within the RISC OS environment (this satisfies requirement 2). Ideally, all
device drivers written for RISC OS 3 should use this interface.
c) By adding joystick devices to Devices:$.Joystick. ISVs can replace or add
whatever joysticks are required (this satisfies requirements 3 and 4).
d) The DeviceFS interfaces are already documented. This reduces the amount
of additional work which would have to go into documenting any new device
driving algorithm (eg. implementing a polling vector). This satisfies
requirement 5.
e) An unbuffered device driver has not been written for DeviceFS. Development of
this software will test that aspect of DeviceFS.
f) We demonstrate that DeviceFS is the correct way to implement device drivers.
Disadvantages:
a) It may not be as fast as the previously described methods (although it should
still be sufficiently fast).
b) This is the method most incompatible with RISC OS 2 (DeviceFS does not exist).
If this method were to be used I suspect that ISVs who write software that
uses joysticks would create their own SWI interface in a seperate module.
For RISC OS 3 this SWI would open the joystick devices and read from them.
For RISC OS 2 a module could be written which provides the same SWI but this
time it would have to read the state of a joystick directly (this would be
hardware dependent). This means that there will still be all manner of
non-standard SWI interfaces which merely interface to the OS_Find and OS_BGet
SWIs.
A more detailed description of the DeviceFS implementation follows, skip it if
there is too much detail.
Device Driver Under DeviceFS
----------------------------
The joystick device driver would take the form of a module called Joystick (as long
as this name has not been registered with us already).
Module workspace:
- keep the following information for each device:
- device driver handle (passed back from DeviceFS_Register, 0 if dead)
- DeviceFS stream handle (passed in DeviceDriver_Entry Initialise)
- internal stream handle (0 if not open)
- address from which to read the joystick state
The module would do the following on initialisation:
- allocate the module workspace
- open the messages file
- set device driver handle for both devices to 0
- if <Joystick$Path> is not set then
set Joystick$Path Devices:$.Joystick.
- this allows joystick devices with names like Joystick:0
The module would respond to the following Services:
Service_DeviceFSStarting
- if hardware doesn't exist then
return
- there must be a seperate device for each joystick so that ISVs can
provide additional joysticks (ie. can't use one joystick device with
special fields as the whole device would be replaced).
- if the device driver handle for either device is non-0 then
error "Devices already registered"
- register joystick 0 using DeviceFS_Register
r0 = 0 (character device, not full duplex)
r1 = pointer to the following
offset 0: offset to "Joystick.0"
4: 0 (no path, unbuffered)
8: 0 (no flags)
12: 0 (no buffers so 0 size)
16: 0 (read only so no transmit flags)
20: 0 (read only so 0 size)
r2 = address of device driver entry point for joystick 0
r3 = 0 (private word)
r4 = workspace pointer
r5 = 0 (no special fields)
r6 = -1 (unlimited readers)
r7 = 0 (no writers)
- store device driver handle for joystick 0
- register joystick 1 using DeviceFS_Register
r0 = 0 (character device, not full duplex)
r1 = pointer to the following
offset 0: offset to "Joystick.1"
4: 0 (no path, unbuffered)
8: 0 (no flags)
12: 0 (no buffers so 0 size)
16: 0 (read only so no transmit flags)
20: 0 (read only so 0 size)
r2 = address of device driver entry point for joystick 1
r3 = 0 (private word)
r4 = workspace pointer
r5 = 0 (no special fields)
r6 = -1 (unlimited readers)
r7 = 0 (no writers)
- store device driver handle for joystick 1
- set the following system variables
set Joystick$Device0 Joystick:0
set Joystick$Device1 Joystick:1
- software which uses joysticks should read these system variables to
determine which joystick devices to use.
- device driver entry points merely set up a pointer to the appropriate
device information and then branch to a generic device handler.
Service_DeviceFSDying
- make sure that device driver handle for both devices is 0
Service_DeviceDead
- if device driver handle == 0 then
set handle for both drivers to 0
else
find device with specied handle
if found then set its handle to 0
The device driver for joystick 0 would do the following:
- set pointer to device record for joystick 0
- branch to generic device driver
The device driver for joystick 1 would do the following:
- set pointer to device record for joystick 1
- branch to generic device driver
The generic device driver would respond to the following calls:
DeviceDriver_Entry 0 (Initialise)
- if internal stream handle in device record != 0 then
error "Stream already exists"
- store DeviceFS stream handle in the device record
- create an internal stream handle
- return internal handle
- handle is not stored in the device record yet, that is done
by DeviceDriver_Entry 11 (Stream created)
DeviceDriver_Entry 1 (Finalise)
- set internal handle in device record to 0
DeviceDriver_Entry 3 (Wake up for RX)
- if internal handle in device record == 0 then
error "Device has not been opened"
- read twice from the address in the device record to get state
- call DeviceFS_ReceivedCharacter to pass back state
r0 = state
r1 = DeviceFS stream handle in device record
DeviceDriver_Entry 11 (Stream created)
- if internal stream handle in device record != 0 then
error "Stream already exists"
- store the internal handle in the device record
- the device record is now valid and state can be read from the
joystick device
The module would do the following when it dies:
- deregister both joystick devices using DeviceFS_Deregister
- close the messages file
- free the module workspace
The module would have no SWIs of its own and would not use any vectors.
ISV Joystick Device Drivers Under DeviceFS
------------------------------------------
ISVs could produce drivers for their own joystick devices in the same manner
as above. However, when their module received Service_DeviceFSStarting
they would look for Devices:Joystick to determine whether any joystick
devices had been registered already. If they had then their module
would register its devices with numbers starting from the highest joystick
number + 1 (unless they wished to replace the built-in joysticks, in which
case the module would register devices 0 and 1 which would kill the original
devices). The module would set Joystick$Device? system variables for
the joystick devices it created.
DeviceFS and Software Which Uses Joysticks
------------------------------------------
Any new software should use the joystick devices directly, ie. open the
required joystick device using OS_Find then read its state using OS_BGet
(then close the device when the software terminates). This means that
the software always accesses joysticks in exactly the same way whether
they are built-in or added on and there is no requirement for options
to select the type of joystick. The software can read the system
variables <Joystick$Device?> in order to get the devices to be used
for input. In this way the user can specify which joystick to use in
an independent way.
Existing software which uses a SWI interface for joysticks will need a
module which replaces the appropriate SWIs. The replacements should
read from the joystick devices in Devices:$.Joystick using the system
variables defined by the drivers eg.
SWI Read_Joy0
if joystick 0 flag not set then
open "<Joystick$Device0>"
set joystick 0 flag
read state from device and return it
Question
--------
Should the interface we provide be easy to simulate on RISC OS 2 machines?
For the vector and DeviceFS methods this would not be easy. I suspect that
what software developers will do if we used one of these two methods is
to write a module which provides a simple SWI interface which hides the
real mechanism. This is a strong argument for just providing a simple
SWI interface ourselves which could then be adopted as a standard interface
for both RISC OS 3 and RISC OS 2. The only drawback with the simple SWI is
that ISVs would have to create a different interface for software which
uses more than two joysticks.
Recommendations
---------------
If the answer to the above question is no (or it doesn't really matter) then
we should go with DeviceFS. After all, we have produced DeviceFS in order to
specify a standard interface to devices. It allows ISVs who produce add-on
joysticks to add them in a clearly defined way (through DeviceFS) and software
which uses joysticks can access built-in or ISV supplied devices in exactly
the same way.
If the answer to the above question is yes then the simple SWI interface is
the most suitable. I suspect that this would also be the most popular choice
with external developers (hence the choice which would probably make us
the most money).
SOFTWARE FUNCTIONAL SPECIFICATION
=================================
Joystick Module for Risc OS Black
---------------------------------
Issue: F
Author: W.Turner
Date: 14th February 1995
Drawing Number: 1303,002/FS
Last Issue: E
________________________________________________________________________________
1. History
Version Date Notes
0.01 30-03-94 Initial draft
0.02 12-05-94 SWI interface changed after FS Review
0.03 08-06-94 Changed to reflect support of ADVAL & OSBYTEs
0.04 03-11-94 Added analogue calibration support
0.05 30-01-95 Added description of !Calibrate support application
0.06 01-02-95 Spec changed as a result of MED-04469
0.07 14-02-95 Spec changed as a result of some other MED faults
2. Outstanding Issues
There are no outstanding issues
3. Product Overview
The joystick module for Risc OS Black is to provide support for up to two
joysticks on a MORRIS platform (eg Kryten). It will support both Atari-style
(digital, one fire button) and PC-style (analogue, 2 fire buttons) joysticks.
At any given time though, only one mode of operation will be required due to
| the hardware implementation (jumpers on the interface board configure the
| interface type).
| To enable a wide variety of analogue joysticks to be used, an application
| will be supplied that allows the joysticks to be calibrated from the desktop.
| This prevents the need for each program to include its own calibration routines.
4. Concepts & Definitions
As per the PC-style joystick standard, the voltage minima & maxima are as
defined in the diagram below, for analogue joysticks. In the software, the
default range will be -127 to +127, in order to match the existing SWI.
Alternatively, 16-bit values can be returned, depending on a SWI flag (see
section 6).
| Note that not all 'PC-style' analogue joysticks adhere to the standard, but
| these are corrected on a calibration, so that they appear to comply to the
| standard.
^ MaxY (Up)
|
|
MinX (Left) <-----+-----> MaxX (Right)
|
|
v MinY (Down)
For digital (atari-type) joysticks, Left = -64, Right = 64, Down = -64 and
Up = 64. Any other value is assumed to be the 'centred' position.
5. User Interface
There are no *commands supported by this module. Note that the module
determines the interface type at initialisation, so dynamic configuration of
the interface is not possible.
| An application called !Calibrate is supplied with the joystick module. This
| allows the user to calibrate analogue joysticks before use (this is necessary
| because of the variations in joystick design). Once this application has
| been run by the user, the returned analogue values from the Joystick_Read
| SWI will cover the full range (0-65535), rather than an arbitrary subset.
6. Programmer Interface
The new module is intended to use a very similar (and backwards-compatible)
| calling interface to the module developed for the A3010. It also defines two new
| SWIs to enable calibration of analogue joysticks.
SWI: Joystick_Read (&43F40)
Returns the state of a joystick
On entry
R0 bits 0-7: joystick number
bits 8-15: reason code: 0 -> return 8-bit values
1 -> return 16-bit values (only applicable
to analogue)
bits 16-31: reserved (0)
On exit
If Reason code = 0 (return 8-bit values)
R0
Byte Value
0 Signed Y axis value, range -127 to +127
1 Signed X axis value, range -127 to +127
2 Switch statuses, starting in bit 0.
3 Reserved
If Reason code = 1 (return 16-bit values)
R0 bits 0-15: Unsigned Y value in the range 0 to 65535
bits 16-31: Unsigned X value in the range 0 to 65535
R1 bits 0-7: Switches (eg fire buttons) as specified in RO3 PRMs
bits 8-31: Reserved
Interrupts
Interrupt status is unaltered
Fast interrupts are enabled
Processor mode
Processor is in SVC mode
Re-entrancy
Not defined
Use
This SWI is used to obtain the state of the requested joystick.
If the hardware interface is configured for an analogue joystick, then the
initial call to the SWI will always return X=0, Y=0, no switches closed.
The analogue routine makes use of a VSync-driven periodic routine that
updates a 'magic location' with the latest readings. This allows the SWI to
quickly read these locations & return, without the unacceptable overhead of
having to wait for a conversion to complete. The digital routine simply looks
directly at the hardware for the latest readings.
If the interface is configured to analogue, then the standard ADC OSBYTEs are
also available (16, 17, 128, 188 - 190), as is the ADVAL command in BASIC.
This is to retain backwards compatibility with the I/O Podule. Note that the
15-pin joystick connector is differently wired to the I/O Podule's ADC port, and
so some kind of adaptor cable will be required to allow ADC port devices to be
connected to the joystick port. Also, the ADC port only supports 2 switches,
whereas the joystick port provides four (2 per joystick). For the ADVAL and
OSBYTE commands, the ADC port device switch should be mapped to fire button 0.
Also, note that if both a joystick interface and an I/O podule are present in
the machine, that the OSBYTEs and ADVAL command will be linked to the ADC
port on the I/O podule. The SWI will still access the joystick port though.
| SWI: Joystick_CalibrateTopRight (&43F41)
|
| One of the pair of SWIs to calibrate an analogue joystick so that the Read
| SWI returns the full range of values (0 to 65535 or -128 to +128)
|
| On Entry
| No entry parameters
|
| On Exit
| All registers preserved
|
| On calling this SWI, the joystick should be in the top-right position.
|
|
| SWI: Joystick_CalibrateBottomLeft (&43F42)
|
| One of the pair of SWIs to calibrate an analogue joystick so that the Read
| SWI returns the full range of values (0 to 65535 or -128 to +128)
|
| On Entry
| No entry parameters
|
| On Exit
| All registers preserved
|
| On calling this SWI, the joystick should be in the bottom-left position.
|
| NOTE: After one of these SWIs has been called, the ADVAL and Read SWI return
| errors until the other calibration SWI is called.
7. Standards
The code is assembled with !ObjAsm.
8. Data Interchange
There are no data interchange formats defined by this project.
9. Data Formats
There are no new data formats defined by this project.
10.External Dependencies
Medusa hardware
MORRIS (for analogue joystick)
Digital Joystick board prototype (required for both digital & analogue)
11.Acceptance Test
Must function on Medusa & Kryten hardware. Also, in analogue mode, the
Vsync-attached routine should not consume more than 1% of the CPU time in
mode 13 (320x256x256, a common games mode) on the Kryten hardware.
Should require less than 3Kb of memory for the module and its workspace.
12.Development Test Strategy
A program will be written to graphically relay the values being read
from the joystick to the screen. This will allow the linearity of the
analogue response to be tested, as well as to ensure the joystick module
allows equal range for both axes, and an acceptable response time.
note that it may be wise to try a selection of joysticks, as resistances
(and thus, overall range) will vary between them.
12345678901234567890123456789012345678901234567890123456789012345678901234567890
TECHNICAL FUNCTIONAL SPECIFICATION
==================================
Joystick Module for Risc OS Black
---------------------------------
Issue: 1
Author: W.Turner
Date: 31st March 1994
Last Issue: n/a
________________________________________________________________________________
This document aims to set out the technical structure of the joystick module to
be developed for Kryten.
Note that this document only covers analogue joysticks, as the existing code is
sufficient to handle digital joysticks.
Due to the (comparatively) long length of time that an A->D conversion takes, it
is impractical to expect the SWI to wait for a complete conversion before
returning.
As a result, it is proposed that a periodic routine be used to update a 'magic'
memory location with the value of the last A->D conversion performed & then
initiate the next conversion.
The SWI then need only look at the contents of this 'magic' location to find the
most recent A->D result, and can return almost instantaneously.
Also, to prevent the periodic routine from claiming processor time when the
joystick module is not in use, it is proposed that the first call to the SWI shall
return a 'centred' result, and start the periodic routine. As the joystick SWI is
likely to be called frequently, this erroneous result will be short-lived, and so
sohuld not adversely affect the calling application.
For the implementation of the periodic routine, there are two possibilities:
1) Interrupt-driven
The joystick interface board has the capability to generate an interrupt when
some combination of A->D conversions have completed. The valid combinations are:
any channel (mask available), all of the channels, the joystick 1 pair, the
joystick 2 pair.
Hence, depending on the IRQ type, any or all of the channels may be in a
readable state. An attempt must not be made to read a channel which does not have
it's 'conversion complete' line asserted, as the wrong value will be read.
2) Polled
The interrupt line from each of the A->D convertors is available in a register,
and so can be read to see whether the conversion has finished. Thus, a periodic
routine could be attached to (say) the OS_CallEvery vector, to read the states.
The advantage of the polled routine is that it will be called at regular pre
-defined intervals, thus creating a constant load on the processor, which may be
important for games.
The interrupt driven routine however, will be called more frequently as the
joystick position moves to the SW corner, as the conversion times will become
faster. This may lead to timing problems in games.
Note also that should the Irq-driven route be taken, then an extra SWI would be
useful to set the irq conditions (ie which channels to monitor, and on what
condition to interrupt)
The second option (Polled) was taken, and the polling routine attached to the
VSync event.
Programming overview of version 0.10
------------------------------------
Need storage locations for 4 AD port values (8-bits each),
Fire bits can be read on the spot a la digital
---
SWI
---
On SWI entry, determine i/f type (D or A). If D, do existing
code & exit.
If A, is it the first call to this SWI? If so, set the
ticky routine going.
Read the values from the magic memory & exit.
-------------
Ticky routine
-------------
On entry, it checks all the AD port 'stop' bits.
For each port with the stop bit set, it updates their
'magic' location, & resets it to do the next conversion.
End
NB: To 'reset' the conversion, write a 0 to the cntcl bit and
a 1 to the dchg bit. After a delay (unknown as yet), write a
0 to the dchg bit and a 1 to the cntcl bit.
\ No newline at end of file
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
# Copyright 1996 Acorn Computers Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Makefile for Joystick
#
# ***********************************
# *** C h a n g e L i s t ***
# ***********************************
# Date Name Description
# ---- ---- -----------
# 25-May-94 AMcC Created.
#
#
# Paths
#
EXP_HDR = <export$dir>
#
# Program specific options:
#
COMPONENT = Joystick
SOURCE = s.Front
TARGET = rm.Joystick
EXPORTS = ${EXP_HDR}.${COMPONENT}
RDIR = Resources
LDIR = ${RDIR}.${LOCALE}
#
# Export Paths for Messages module
#
RESDIR = <resource$dir>.Resources2.${COMPONENT}
#
# Generic options:
#
MKDIR = cdir
AS = aasm
CP = copy
RM = remove
CCFLAGS = -c -depend !Depend -IC:
ASFLAGS = -depend !Depend -Stamp -quit -module -To $@ -From
CPFLAGS = ~cfr~v
#
# Generic rules:
#
rom: ${TARGET}
@echo ${COMPONENT}: rom module built
export: ${EXPORTS}
@echo ${COMPONENT}: export complete
install_rom: ${TARGET}
${CP} ${TARGET} ${INSTDIR}.${COMPONENT} ${CPFLAGS}
@echo ${COMPONENT}: rom module installed
resources:
${MKDIR} ${RESDIR}
${CP} ${LDIR}.Messages ${RESDIR}.Messages ${CPFLAGS}
@echo ${COMPONENT}: resource files copied to Messages module
clean:
${RM} ${TARGET}
@echo ${COMPONENT}: cleaned
${TARGET}: ${SOURCE}
${AS} ${ASFLAGS} ${SOURCE}
${EXP_HDR}.${COMPONENT}: hdr.${COMPONENT}
${CP} hdr.${COMPONENT} $@ ${CPFLAGS}
# Dynamic dependencies:
| Copyright 1996 Acorn Computers Ltd
|
| Licensed under the Apache License, Version 2.0 (the "License");
| you may not use this file except in compliance with the License.
| You may obtain a copy of the License at
|
| http://www.apache.org/licenses/LICENSE-2.0
|
| Unless required by applicable law or agreed to in writing, software
| distributed under the License is distributed on an "AS IS" BASIS,
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
| See the License for the specific language governing permissions and
| limitations under the License.
|
Dir <Obey$Dir>
amu_machine clean
| Copyright 1996 Acorn Computers Ltd
|
| Licensed under the Apache License, Version 2.0 (the "License");
| you may not use this file except in compliance with the License.
| You may obtain a copy of the License at
|
| http://www.apache.org/licenses/LICENSE-2.0
|
| Unless required by applicable law or agreed to in writing, software
| distributed under the License is distributed on an "AS IS" BASIS,
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
| See the License for the specific language governing permissions and
| limitations under the License.
|
Dir <Obey$Dir>
amu_machine rom
NoHWare:Joystick hardware not present
BadJoy:Joystick number out of range
; > Version
;; History:
GBLA Version
GBLS VString
GBLS Date
Version SETA 0022 ; 0021
VString SETS "0.22" ; "0.21"
Date SETS "07 Mar 1995" ; "07 Mar 1995"
END
; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
SUBT Exported Joystick constants
OldOpt SETA {OPT}
OPT OptNoList+OptNoP1List
; ***********************************
; *** C h a n g e L i s t ***
; ***********************************
;
; Date Name Description
; ---- ---- -----------
; 14-Oct-91 SMC Created
; 17-May-94 AMcC Changed to using the preferred SWI base and name symbols
SWIClass SETS JoystickSWI_Name
^ JoystickSWI_Base
AddSWI Read ; &43F40
AddSWI CalibrateTopRight ; &43F41
AddSWI CalibrateBottomLeft ; &43F42
OPT OldOpt
END
*
!.gitignore
*
!.gitignore
; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; > Sources.Front
;;-----------------------------------------------------------------------------
;; Joystick device driver.
;;
;; Change list
;; 0.01 SMC Created
;; 0.02 12-Mar-92 SMC No longer refuses to initialise if the message file can't
;; be opened (now only opened if required).
;; Read location twice when checking for hardware.
;; 0.03 08-Feb-93 SMC Use Hdr: to get headers.
;; 0.04 14-Jan-94 SMC Don't free workspace in finalisation (could break RMTidy).
;; 0.09 31-Mar-94 WT Analogue support added, and digital support rewritten
;; for Kryten/Morris joystick interface board.
;; 0.10 12-May-94 WT Analogue support altered to support optional returning
;; of the full 16-bit value for analogue joysticks.
;;
;;-----------------------------------------------------------------------------
Module_BaseAddr
GET Hdr:ListOpts
GET Hdr:Macros
GET Hdr:System
GET Hdr:ModHand
GET Hdr:MsgTrans
GET Hdr:NdrDebug
GET Hdr:Podule
GET Version
GBLL hostvdu
GBLL debugmod
GBLL debugtmp
GBLL debugwt
debug SETL false
debugmod SETL false ; Module debug
debugtmp SETL false ; Temporary debug
debugwt SETL false ; Misc debugging by WT
hostvdu SETL false
; ----------------------------------------------------------------------------------------------------------------------
DigitalJoystickAddress * &0302B800 ; NetCS
AnaDigiDetect * &0302B000 ; NetROM
AnalogueJoyFire * DigitalJoystickAddress
AnalogueIrqReg * &032000e0 ; Provisional MORRIS address
AnalogueStatusReg * &032000e4 ; " " "
AnalogueControlReg * &032000e8 ; " " "
AnalogueChan1Count * &032000ec ; " " "
AnalogueChan2Count * &032000f0 ; " " "
AnalogueChan3Count * &032000f4 ; " " "
AnalogueChan4Count * &032000f8 ; " " "
AnalogueJoyCnt * &0f
AnalogueJoyDchg * &f0
AnalogueJoy0Cnt * &03
AnalogueJoy1Cnt * &0C
AnalogueJoy0Dchg * &30
AnalogueJoy1Dchg * &C0
AnalogueChn1Cnt * &01
AnalogueChn2Cnt * &02
AnalogueChn3Cnt * &04
AnalogueChn4Cnt * &08
AnalogueChn1Dchg * &10
AnalogueChn2Dchg * &20
AnalogueChn3Dchg * &40
AnalogueChn4Dchg * &80
Joy0_Completed * 3 :SHL: 0
Joy1_Completed * 3 :SHL: 2
Chn1_Completed * 1 :SHL: 4
Chn2_Completed * 1 :SHL: 5
Chn3_Completed * 1 :SHL: 6
Chn4_Completed * 1 :SHL: 7
Any_Completed * 15 :SHL: 4
DigitalUpBit * 1 :SHL: 0
DigitalDownBit * 1 :SHL: 1
DigitalLeftBit * 1 :SHL: 2
DigitalRightBit * 1 :SHL: 3
DigitalFireBit * 1 :SHL: 4
AnalogueJoy0Fire * 3 :SHL: 0
AnalogueJoy1Fire * 3 :SHL: 8
AnalogueAdvalFireA * 1 :SHL: 0
AnalogueAdvalFireB * 1 :SHL: 8
UpCode * &00040 ; 64 in byte 0
DownCode * &000C0 ; -64 in byte 0 (signed)
LeftCode * &0C000 ; -64 in byte 1 (signed)
RightCode * &04000 ; 64 in byte 1
FireCode * &10000 ; 1 in byte 2
Top8Bits * &FF00 ;For sig bit test
Bottom8Bits * &00FF ;
MaxADCChannel * 4 ;Highest logical ADC channel
Service_UKByte * &07 ;Service call claimed to support ADVAL
Service_UKCommand * &04 ;Unknown command service call
; ----------------------------------------------------------------------------------------------------------------------
; Workspace layout
workspace RN R12
^ 0,workspace
message_file_open # 4
message_file_block # 4*4
magic_chan_one # 4
magic_chan_two # 4
magic_chan_three # 4
magic_chan_four # 4
range_chan_one # 4 ;Split XXXXYYYY where XXXX is max-min, YYYY is min
range_chan_two # 4 ;
range_chan_three # 4 ;
range_chan_four # 4 ;
range_polarity # 1 ;Stores the polarity of each axis
misc_flags # 1
adc_numchanstosample # 1
adc_lastconversion # 1
defaultrange * &1000 ;These happen to suit Quickshot Warrior (cheap & nasty!)
defaultmin * &30 ;PC-compatible joysticks
SixteenBitFlag * 1 ;This is a SWI entry flag, _NOT_ a misc flag
NoJoystickFlag * 1 :SHL: 0 ;However, these _ARE_ the misc flags!
FirstTimeFlag * 1 :SHL: 1
CalibrateFlag * 1 :SHL: 2
AnalogueFlag * 1 :SHL: 3
RstChan1Flag * 1 :SHL: 4
RstChan2Flag * 1 :SHL: 5
RstChan3Flag * 1 :SHL: 6
RstChan4Flag * 1 :SHL: 7
RstFlags * 15 :SHL: 4
polarity_chan_one * 1 :SHL: 0
polarity_chan_two * 1 :SHL: 1
polarity_chan_three * 1 :SHL: 2
polarity_chan_four * 1 :SHL: 3
default_polarities * &A ;ie reverse Y-axes only (suits most PC joysticks)
max_running_work * :INDEX:@
! 0, "Module workspace is &":CC:(:STR:(:INDEX:@)):CC:" bytes"
; ----------------------------------------------------------------------------------------------------------------------
LNK s.ModHead
; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; > Sources.ModHead
LEADR Module_LoadAddr
ASSERT (.=Module_BaseAddr)
DCD 0 ; Start
DCD Init - Module_BaseAddr
DCD Die - Module_BaseAddr
DCD Service - Module_BaseAddr ; Service
DCD Title - Module_BaseAddr
DCD Helpstr - Module_BaseAddr
DCD 0 ; Helptable
DCD &43f40 ; SWIbase
DCD SWIhandler - Module_BaseAddr
DCD SWInames - Module_BaseAddr
DCD 0 ; SWIdecode
DCD 0
DCD 0
; ---------------------------------------------------------------------------------------------------
Title DCB "Joystick",0
Helpstr DCB "Joystick",9,"$VString ($Date)",0
ALIGN
; ---------------------------------------------------------------------------------------------------
; Module initialisation point
Init
Push "lr"
Debug mod,"Initialising"
LDR r0,[r12] ; Have we already got a workspace ?
CMP r0,#0 ; clears V
MOVNE r12,r0
BNE %FT01
MOV r0,#6
LDR r3,=max_running_work
SWI XOS_Module ; Claim workspace
Pull "pc",VS
STR r2,[r12] ; Store workspace pointer.
MOV r12,r2
01
MOV r0,#0
STR r0,message_file_open
; Test for existance & type of hardware. Read from the Type detection address
; If bit 3 is set, then digital. If bits 4-7 = 1000 then present
Debug mod,"Checking hardware"
; LDR r0, =AnaDigiDetect
; LDRB r1,[r0]
MOV r0, #1<<5
ADR r1, magic_chan_one ;safe to use this temporarily
MOV r2, #4
MOV r3, #8 ;network slot is podule 8
SWI XPodule_ReadInfo
MOVVS r1, #0
LDRVC r1, magic_chan_one ;r1 contains the podule id byte in bits 0->7
Debug wt,"Read back from type detect:",r1
AND r0, r1, #&f0 ; Check for hardware first
CMP r0, #&10
BNE NoHware
ANDS r1, r1, #AnalogueFlag ; Pick out the Ana/Digi flag
; ORR r1, r1, #RstFlags ; Set the reset flags too
STRB r1, misc_flags ; And store it away, zeroing the rest of the misc flags too.
BLNE init_analogue ; And then go set it in action...
;Initialise any other flags
LDRB r1, misc_flags
ORR r1, r1, #FirstTimeFlag ; Set the first-time flag
STRB r1, misc_flags
Debug wt,"Misc flags stored as:",r1
;Ok, lets bung some 'sensible' defaults into the ranges...
MOV r1, #defaultrange << 16
ORR r1, r1, #defaultmin
STR r1, range_chan_one
STR r1, range_chan_two
STR r1, range_chan_three
STR r1, range_chan_four
;And set up the polarities for a TL min, BR max (like most PC analogue sticks)
;to give BL min, TR max as in the SWI
MOV r1, #default_polarities
STRB r1, range_polarity
Pull "pc" ; Hardware is there so initialise successfully.
NoHware
Debug mod,"No hardware"
ADR r0,ErrorBlock_NoHardware
BL msgtrans_errorlookup
BL Shut_Down
SETV
Pull "pc"
ErrorBlock_NoHardware
DCD &43f40
DCB "NoHWare",0
ALIGN
; ---------------------------------------------------------------------------------------------------
; RMKill'ing the module
Die
Push "r4,lr"
MOV r4, r12 ; So we can release the ticker if need be
LDR r12, [r12]
CMP r12, #0
Pull "r4, pc",EQ,^ ; Looks like we didn't even get as far as claiming workspace!
MOV r0,#7
MOV r2,r12
SWI XOS_Module ; Clear workspace
BL StopTickyRoutine
BL Shut_Down
Pull "r4,pc",,^
StopTickyRoutine
Push "r0-r2,lr"
LDRB r0, misc_flags
Debug wt,"Misc flags read as",r0
TST r0, #FirstTimeFlag
Pull "r0-r2,pc",NE ; If set, then no ticker to stop!
Debug wt,"Um, think we have a vector registered"
MOV r0, #13
MOV r1, #4
SWI XOS_Byte ; Disable VSync event
MOV r0, #&10 ; Event vector
ADR r1, TickerRoutine
MOV r2, r4
SWI XOS_Release ; Release the ticker routine
Pull "r0-r2,pc"
Shut_Down
Push "r0,lr"
Debug mod,"Module dying"
; Close the message file if it's open
LDR r0,message_file_open
TEQ r0,#0
ADRNE r0,message_file_block
SWINE XMessageTrans_CloseFile
Pull "r0,pc"
; ---------------------------------------------------------------------------------------------------
; Initialising the analogue registers in Morris
init_analogue
LDR r1, =AnalogueIrqReg
MOV r0, #&0f ;Enable all channels, but don't allow irqs
STRB r0, [r1] ;
LDR r1, =AnalogueControlReg
MOV r0, #&0f ;Counters on, discharge off
STRB r0, [r1]
MOV pc,lr
LNK s.ticky
; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; > Sources.SWI
SWInames
DCB "Joystick",0
DCB "Read",0
DCB "CalibrateTopRight",0
DCB "CalibrateBottomLeft",0
DCB 0
ALIGN
; --------------------------------------------------------------------------------------------------
; There are only three SWIs. As this is unlikely to change we don't need a jump table
; and can save some space.
SWIhandler
ROUT
Push "r2-r5,lr"
Push "r1"
CMP r11, #3
BGT %FT01
MOV r4, r12 ; Just in case it's the first time...
LDR r12,[r12] ; Get workspace from private word
ADD pc, pc, r11, LSL #2 ; Jumptable calculation
MOV r0, r0 ; dummy instruction
B AreWeAnaOrDigi ; Oh look! it's a jumptable after all...
B Calib_SWIS ; If it's the calibrationTL SWI, then go do it...
B Calib_SWIS ; If it's the calibrationBR SWI, then go do it...
01 ADR r0,ErrorBlock_BadSWI ; Uh Oh!
addr r4, Title
BL msgtrans_errorlookup
Pull "r1",VS
Pull "r2-r5,pc",VS
;----------------------------------------------------------------------------------------
ErrorBlock_BadSWI
DCD &112
DCB "BadSWI",0
ALIGN
ErrorBlock_BadJoystick
DCD &43f41
DCB "BadJoy",0
ALIGN
AreWeAnaOrDigi
;Don't upset R0 or R4!
LDRB r2, misc_flags
TST r2, #CalibrateFlag
BNE %FT05
TST r2, #AnalogueFlag ; Check the ana/digi flag
BEQ Joystick_ReadDigSWICode ; Bleugh. Digital sticks are no good for flight-sims!
Debug wt,"Analogue-read code"
TST r2, #FirstTimeFlag ; Check the first time flag if we're analogue
BEQ %FT20 ; Not first time, so don't set the ticky thing going
BL StartTickyRoutine ; If set, special case...
Debug wt,"Ticky tick tick started"
05 MOV r0, #0 ; Dummy value to return from the SWI (centred joystick)
Pull "r1"
Pull "r2-r5,pc" ; All done, let's go
; Drop through to...
Joystick_ReadAnaSWICode
; In: r0 = Joystick number
20 MOV r5, r0, LSR #8 ; R5 contains the flag info now
AND r0, r0, #&FF ; Mask off the flags from R0
ADR r1, magic_chan_one
ADR r2, magic_chan_two
LDR r3, =AnalogueJoyFire
CMP r0, #1 ; Did we want Joystick 1 though?
ADREQ r1, magic_chan_three
ADREQ r2, magic_chan_four
CMPNE r0, #0 ; No, but did we really want Joystick 0?
ADRNE r0,ErrorBlock_BadJoystick ; Nope, so it's not a valid joystick ( >1 )
BLNE msgtrans_errorlookup
Pull "r1",VS
Pull "r2-r5,pc",VS ; Return if error
;Now sort out the fire buttons, into R4
LDR r4, [r3] ; Latch &
LDR r4, [r3] ; load
MOV r3, #0
CMP r0, #0 ; Joystick 0??
ANDEQ r3, r4, #AnalogueJoy0Fire ; YES - Pick out Joystick 0 fire buttons
EOREQ r3, r3, #AnalogueJoy0Fire ; YES - Invert them
MOVEQ r4, r3, LSL #16 ; YES - Put in byte 2 of R4
ANDNE r3, r4, #AnalogueJoy1Fire ; NO - Pick out Joystick 1 fire buttons
EORNE r3, r3, #AnalogueJoy1Fire ; NO - Invert them
MOVNE r4, r3, LSL #8 ; NO - Put in byte 2 of R4
;Do twiddling to go from raw to 16 or 8 bits scaled
LDR r1, [r1] ; Read the X channel
LDR r2, [r2] ; Read the Y channel
MOV r3, #&ff
ORR r3, r3, r3, LSL #8 ; Now we have &ffff in r3
AND r1, r1, r3 ; Clear the top 16 bits from r1...
AND r2, r2, r3 ; ... and from R2.
;Now scale to cover the entire 16-bit range (0 -> &ffff)
BL ExpandRange ; NB: This routine needs the joystick number in R0!
TST r5, #SixteenBitFlag ; Do we want 16 or 8 bit results?
BNE %FA30 ; Sixteen, so jump
MOV r3, r1, LSR #8 ; If 8-bits,
TST r3, #1<<7 ;bit 7 set?
BICNE r3, r3, #1<<7 ;Clear top bit then.
EOREQ r3, r3, #&ff ;Nope, so invert all bits.
MOV r1, r3 ; this bit
MOV r3, r2, LSR #8 ; twiddling
TST r3, #1<<7 ;bit 7 set?
BICNE r3, r3, #1<<7 ;Clear top bit then.
EOREQ r3, r3, #&ff ;Nope, so invert all bits.
MOV r2, r3 ; .
;Put the values into the result word if 8-bit values wanted
MOV r0, r4
ORR r0, r0, r2 ; Put the Y in the result
ORR r0, r0, r1, LSL #8 ; Put the X in the result
Pull "r1"
Pull "r2-r5,pc" ; All done, let's go
;Put the values into the result word, unsigned
30 Pull "r5" ; Pull r1 into r5 so we can fill it instead...
MOV r0, r2 ; Put the Y axis value in R0
ORR r0, r0, r1, LSL #16 ; Put the X axis value in R0
MOV r1, r4, LSR #16 ; Put switch bits in R1, bottom byte
Pull "r2-r5,pc" ; End of story
;----------------------------------------------------------------------------------------
Joystick_ReadDigSWICode
; In: r0 = Joystick number - can't get 16-bit values from digital
Debug wt,"Digital-read code"
LDR r1, =DigitalJoystickAddress
LDR r2, [r1] ; Latch in the current state
LDR r2, [r1] ; Read it (top 16 bits are junk)
Debug wt,"Register contents are",R2
CMP r0, #1 ; Make sure joystick number is 0 or 1
MOVEQ r2, r2, LSR #8 ; Push the joy1 bits into the low byte
AND r2, r2, #&ff ; Assume we mean joy 0 then
CMPNE r0, #0 ; But did we?
ADRNE r0, ErrorBlock_BadJoystick ; Nope, so error & quit
BLNE msgtrans_errorlookup
Pull "r1",VS
Pull "r2-r5,pc",VS
;At this point, we have the joystick info in the low byte of r2
MOV r0, #0 ; Clear R0!
TST r2, #DigitalUpBit ; Put up/down state in byte 0
ORREQ r0, r0, #UpCode
TST r2, #DigitalDownBit
ORREQ r0, r0, #DownCode
TST r2, #DigitalLeftBit ; Put left/right state in byte 1
ORREQ r0, r0, #LeftCode
TST r2, #DigitalRightBit
ORREQ r0, r0, #RightCode
TST r2, #DigitalFireBit ; And finally the fire bit (in byte 2)
ORREQ r0, r0, #FireCode
Debug wt,"Done calculatin'"
Pull "r1"
Pull "r2-r5,pc" ; All done, let's go
;----------------------------------------------------------------------------------------
StartTickyRoutine
Push "lr"
LDRB r1, misc_flags
Debug wt,"Starting Ticky routine: Misc flags are ",r1
BIC r1, r1, #FirstTimeFlag ; Clear the first-time flag
STRB r1, misc_flags
MOV r0, #&10 ; We want the event vector
addr r1, TickerRoutine
MOV r2, r4 ; Puts the private word in R2
SWI XOS_Claim
MOV r0, #14 ; OS_Byte 14
MOV r1, #4 ; Claim VSync event
SWI XOS_Byte
Pull "pc",,^
;----------------------------------------------------------------------------------------
ExpandRange
;On entry, R0=joystick number, R1=Xval, R2=Yval, R3=&ffff, R4=fires, R5=16-bit flag
;On exit, R0=joystick number, R1=scaled Xval, R2=scaled Yval, R3=&ffff, R4=fires, R5=16-bit flag
Push "r0,r3-r6,lr"
Debug wt,"Expanding range!"
CMP r0, #0 ;Joystick 0 or 1?
LDREQ r4, range_chan_one
LDRNE r4, range_chan_three
Debug wt,"X was ",r1
Debug wt,"Range is ",r4
AND r5, r4, r3 ;R5=min calib
SUBS r6, r1, r5 ;R6=value-min
MOVMI r6, #0 ; Don't allow R6 < 0
RSB r6, r6, r6, LSL #16 ;R6=((value-min)<<16) - (value-min)
MOV r4, r4, LSR #16 ;R4=calib range
DivRem r1, r6, r4, r5 ;R1=R6/calib range. R5 is corrupted
CMP r1, r3
MOVPL r1, r3 ;Impose an FFFF max
CMP r1, #0
MOVMI r1, #0 ;and a 0 min
Debug wt,"X is ",r1
;Now do the Y-values
CMP r0, #0 ;Joystick 0 or 1?
LDREQ r4, range_chan_two
LDRNE r4, range_chan_four
AND r5, r4, r3 ;R5=min calib
SUBS r6, r2, r5 ;R6=value-min
MOVMI r6, #0 ; Don't allow R6 < 0
RSB r6, r6, r6, LSL #16 ;R6=((value-min)<<16) - (value-min)
MOV r4, r4, LSR #16 ;R4=calib range
DivRem r2, r6, r4, r5 ;R2=R6/calib range. R5 is corrupted
CMP r2, r3
MOVPL r2, r3 ;Impose an FFFF max
CMP r2, #0
MOVMI r2, #0 ;and a 0 min
;Ranges done, now invert R1,R2 if necessary
LDRB r4, range_polarity
CMP r0, #0
BNE %FT40
TST r4, #polarity_chan_one ;ie X
MVNNE r1, r1 ;invert r1 if so
ANDNE r1, r1, r3
TST r4, #polarity_chan_two ;ie Y
MVNNE r2, r2 ;invert r2 if so
ANDNE r2, r2, r3
Pull "r0,r3-r6,pc"
40 TST r4, #polarity_chan_three ;ie X
MVNNE r1, r1 ;invert r1 if so
ANDNE r1, r1, r3
TST r4, #polarity_chan_four ;ie Y
MVNNE r2, r2 ;invert r2 if so
ANDNE r2, r2, r3
Pull "r0,r3-r6,pc"
;----------------------------------------------------------------------------------------
Calib_SWIS ;R2 to R5 and LR are pushed, as is R1 (separately)
;Need optional checks here to determine axis polarity.
LDRB r2, misc_flags
TST r2, #FirstTimeFlag ; Check the first time flag if we're analogue
BEQ %FT48 ; Not first time, so don't set the ticky thing going
BL StartTickyRoutine ; If set, special case...
Debug wt,"Ticky tick tick started"
MOV r0, #19
SWI OS_Byte ;Wait for a VSync so we get some sensible values...
SWI OS_Byte ;Wait for a VSync so we get some sensible values...
SWI OS_Byte ;Wait for a VSync so we get some sensible values...
48 MOV r1, #&ff
ORR r1, r1, r1, LSL #8 ;R1 is &ffff
LDRB r2, misc_flags
TST r2, #CalibrateFlag
BNE %FT50 ;This is the second calibration!
ORR r2, r2, #CalibrateFlag ;I'm 'aving a CALIBRATE!
STRB r2, misc_flags
LDR r2, magic_chan_one ;Take snaphots
AND r2, r2, r1
STR r2, range_chan_one
LDR r2, magic_chan_two ;Take snaphots
AND r2, r2, r1
STR r2, range_chan_two
LDR r2, magic_chan_three ;Take snaphots
AND r2, r2, r1
STR r2, range_chan_three
LDR r2, magic_chan_four ;Take snaphots
AND r2, r2, r1
STR r2, range_chan_four
Pull "r1"
Pull "r2-r5,pc"
;Right, munge stuff to get range-min pairs & polarities
50 BIC r2, r2, #CalibrateFlag ;Clear the calibrate flag
STRB r2, misc_flags
MOV r2, #0 ;Clear R2 ready to accept polarity flags
LDR r3, magic_chan_one
AND r3, r3, r1
LDR r4, range_chan_one ;Previous reading
MOV r5, #polarity_chan_one
BL DoRanging
STR r3, range_chan_one
LDR r3, magic_chan_two
AND r3, r3, r1
LDR r4, range_chan_two ;Previous reading
MOV r5, #polarity_chan_two
BL DoRanging
STR r3, range_chan_two
LDR r3, magic_chan_three
AND r3, r3, r1
LDR r4, range_chan_three ;Previous reading
MOV r5, #polarity_chan_three
BL DoRanging
STR r3, range_chan_three
LDR r3, magic_chan_four
AND r3, r3, r1
LDR r4, range_chan_four ;Previous reading
MOV r5, #polarity_chan_four
BL DoRanging
STR r3, range_chan_four
Debug wt,"Storing r2 as ",r2
STRB r2, range_polarity
Pull "r1"
Pull "r2-r5,pc"
DoRanging
CMP r3, r4 ;Sort out which way around they are to get the 'range'
BPL %FT60 ;first call was the smaller X1
SUB r4, r4, r3 ;R4 = range now
SUB r4, r4, r4, LSR #12 ;Decrease the range slightly at CWhyte's request :-P
CMP r4, #0
MOVEQ r4, #1
ORR r3, r3, r4, LSL #16 ;Combine the min & range in r3
CMP r11, #1 ;Is this 2nd call the TR?
ORREQ r2, r2, r5 ;Nope, so we need reverse polarity
Debug wt,"After a doranging, r2 is ",r2
MOV pc, lr
60 SUB r3, r3, r4 ;R3 = range now
SUB r3, r3, r3, LSR #12 ;Decrease the range slightly at CWhyte's request :-P
CMP r3, #0
MOVEQ r3, #1
ORR r4, r4, r3, LSL #16 ;Combine the min & range in r4
CMP r11, #1 ;Is this 2nd call the TR?
ORRNE r2, r2, r5 ;Yup, so we need reverse polarity
Debug wt,"After a doranging.., r2 is ",r2
MOV r3, r4
MOV pc, lr
LNK s.Service
; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; > Sources.Service
; ---------------------------------------------------------------------------------------------------
Service
ROUT
TEQ R1, #Service_UKByte
MOVNES pc, lr ;Nowt to do with us then...
Push "r0,r12,lr"
MOV r14, r12 ;Bung R12 into R14 in case we have to start the ticker routine
LDR r12, [r12] ;Get workspace address into R12
;Check the interface is analogue. If not, we don't want to get involved
LDRB r0, misc_flags
TST r0, #AnalogueFlag ;Check the ana/digi flag
Pull "r0,r12,pc",EQ,^ ;It's a digital i/f, so ignore the service
TST r0, #CalibrateFlag ;and the 'calibrate' flag
Pull "r0,r12,pc",NE,^ ;It's being calibrated at the mo, so ignore the service
TST r0, #FirstTimeFlag ;Is the ticky routine going yet?
Push "r0-r5",NE
MOV r4, r14 ;Grab the value of R12 into R4 from R14
BLNE StartTickyRoutine ;Nope, so go start it
Pull "r0-r5",NE
;I know I should be claiming ByteV, but doing it this way is the easiest
;way to ensure that if present, the I/O podule will get to the UKByte first...
;However, it does mean that we can't indicate any errors :-(
AND r2, r2, #&ff ;OS_Byte number
AND r3, r3, #&ff ;Parameter 1
AND r4, r4, #&ff ;Parameter 2
TEQ r2, #16
BEQ OSByte16 ;Select ADC channels to sample
TEQ r2, #17
BEQ OSByte17 ;Force an ADC conversion
TEQ r2, #128
BEQ OSByte128 ;Read ADC channel (ADVAL)
TEQ r2, #188
BEQ OSByte188 ;Read currently-converting ADC channel
TEQ r2, #189
BEQ OSByte189 ;Read maximum ADC channel number
TEQ r2, #190
BEQ OSByte190 ;Read ADC conversion type
05 MOV r1, #Service_UKByte ;Pass it on if it's none of these...
Pull "r0,r12,pc",,^ ;
;-----------------
OSByte16
CMP r3, #4 ; Is r1 greater than 4?
MOVGT r3, #4 ; If so, fix it to 4
STRB r3, adc_numchanstosample; Stuff r1 away
10 MOV r1, #0 ; Claim the service call
Pull "r0,r12,pc",,^ ; and return
;-----------------
OSByte17
B %BT10 ; Claim service & quit, but pretend we did something
;-----------------
OSByte128
; CMP r3, #4
; BLT %BT05 ;Bzzt, wrong answer!
CMP r3, #0
BNE %FT15
;Do the fire bit reading here
LDR r3, =AnalogueJoyFire
LDR r4, [r3] ; Latch &
LDR r4, [r3] ; load
AND r3, r4, #AnalogueAdvalFireA
AND r4, r4, #AnalogueAdvalFireB
ORR r3, r3, r4, LSR #7
LDRB r4, adc_lastconversion
B %FT20
15 TEQ r3, #1
ADREQ r0, magic_chan_one
TEQ r3, #2
ADREQ r0, magic_chan_two
TEQ r3, #3
ADREQ r0, magic_chan_three
TEQ r3, #4
ADREQ r0, magic_chan_four
STRB r3, adc_lastconversion
LDR r0, [r0] ; R0 now contains the channel reading (16bit)
AND r3, r0, #&ff ; R3 (X) contains the low 8 bits
AND r0, r0, #&ff00 ; Clear all but the 2nd 8 bits
MOV r4, r0, LSR #8 ; R4 (Y) contains the high 8 bits now
B %FT20 ; Claim & quit
;-----------------
OSByte188
LDRB r3, adc_lastconversion ; Give 'em any old junk - they'll believe it!
B %FT20
;-----------------
OSByte189
LDRB r3, adc_numchanstosample
20 MOV r1, #0
Pull "r0,r12,pc",,^ ; Claim service & quit
;-----------------
OSByte190
MOV r3, #0 ; We're doing the default (16bit)
B %BT20 ; Claim & quit
;------------------------------------------------
LNK s.Tail
; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; > Sources.Tail
msgtrans_openfile
Push "r0-r2,lr"
ADR r0,message_file_block
ADR r1,message_filename
MOV r2,#0
SWI XMessageTrans_OpenFile
MOVVC r0,#-1
STRVC r0,message_file_open
STRVS r0,[sp]
Pull "r0-r2,pc"
msgtrans_errorlookup
Push "lr"
CLRV
LDR r1,message_file_open
TEQ r1,#0
BLEQ msgtrans_openfile
Pull "pc",VS
ADR r1,message_file_block
MOV r2,#0
SWI XMessageTrans_ErrorLookup
Pull "pc"
message_filename
DCB "Resources:$.Resources.Joystick.Messages",0
ALIGN
; Neil's debugging routines
[ debug
InsertNDRDebugRoutines
]
END
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment