ADFFS v2.88 28/03/26 written by Jon Abbott
------------------------------------------

ADFFS provides emulation of 1772 and 710/711 floppy disc controllers,
by emulating ADFS responses to disc requests.  ADF, APD, HFE and JFD floppy
images can be mounted to ADFS::0 as if they were physically inserted.

To associate floppy image files with ADFFS, ensure their file type is set
to "Floppy" (&FCE).  Mount a floppy image by double clicking the file.

Please ensure your system is configured for at least one floppy drive, this
is then redirected to ADFFS when a disc image is mounted.  For OS builds that
do not include ADFS (eg Pi), a stub ADFS Module implementation is automatically
loaded.

ADFFS supports the following floppy image formats:

F - 1600K, 77 entry directories, new map
E - 800K, 77 entry directories, new map
D - 800K, 77 entry directories, old map
L - 640K, 47 entry directories, old map
Atari 360K
Atari 720K
DOS 720K
DOS 1.44M

ADFFS also has the ability to provide a virtual IOC/MEMC/VIDC1 or VIDC20 based
machine, running RISC OS 2.0 thru RISC OS 3.71.  When games are run via the
"Boot floppy" menu option, this is automatically started if the game won't run
on the machine you're attempting to run it on.

Whilst the VM is active, the current task runs as if it's running on
either an ARM3 or StrongARM processor.  Instructions that aren't supported, or
which behave differently on the physical CPU are translated to suitable
instructions.

The VM also supports software compiled for APCS-A and APCS-R, suitable CLib
Modules are loaded automatically into the VM environment when code attempts
to invoke CLib.

ARM3/StrongARM emulation is handled via a JIT, which examines the code when
it's first seen and only modifies incompatible or ambiguous instructions.
The code then executes natively on the physical CPU, with the JIT only being
invoked when new instructions or self-modifying code execute.

JIT'd ARM3 code executes at a speed roughly equivelant to an ARM3 clocked at
~91% of the physical CPU MHz (Pi3).  For StrongARM code its  ~99%.
This enables games that wouldn't ordinarily run on an ARM6 or ARM7 due
of incompatibilities, to still run faster than they would on an original ARM3.
Likewise a StrongARM can run ARM6/7 code faster than the original CPU's.

ADFFS accounts for CPU speed differences, games are regulated at their
original intended speed and any known bugs are corrected where possible.

When games are run on a machine that has a GPU, the screen is translated to a
16M colour equivelent.  A Pi must be in a 24bit desktop screen mode, ADFFS
will then use the Pi's hardware scaler to upscale the game to the desktop
resolution.
Other machines must support legacy MODE resolutions via an MDF file.

When games coded Archimedes are run on a RiscPC, VIDC1 registers are
translated to VIDC20 on-the-fly and screen writes are redirected to the
RiscPC screen buffer.

When used in conjunction with USBJoystick (which is pre-loaded by ADFFS under
RISC OS 5), Acorn, RTFM and Serial Port/Vertical Twist Joystick interfaces
are emulated and many games that don't natively support Joystick have their
keys mapped to the Joystick.



Commands
--------
*ADFMount <file>
  Load a floppy image file (ADF/APD/JFD) into memory


*ADFOpen <file>
  Load a floppy image file (ADF/APD/JFD) into memory and open a filer window


*ADFSave <file>

  Save a mounted floppy image to harddisc


*ADFEject

  Remove the mounted image from memory.  If the currently mounted image is a
  JFD file with the "Auto flush" setting enabled, any changes will be written
  to the JFD before it is closed


*ADFFlush

  Writes changes back to the currently open ADF/JFD file


*ADFRecord <file>

  Creates a recording file, storing information on all DiscOp's to <file>
  Press Ctrl-Shift-F10 to stop recording or use *ADFStop


*ADFStop

  Stops recording DiscOp's, equivalent to pressing Ctrl-Shift-F10 while
  creating a recording file


*ADFDoNothing [<parameters>]

  Does nothing, use with Set Alias$<Command> to prevent destructive commands
  in game code, such as *Desktop, *Unplug etc


*ADFBootFloppy [<disc ID>] [<parameters>]

  Runs the appropriate build-in game Boot script if one exists or simulates a
  Shift-Break soft-reset to boot a floppy or if a script doesn't exist or was
  not explicitly speficied.
  When used with <disc ID> (eg.*ADFBootFloppy F1000101) it will run the ADFFS
  game Boot script.  This is useful when installing games to harddisc as it will
  ensuring they always using the most recent version of the ADFFS boot script.


*ADFProtectModules [ON | OFF]

  Prevents essential Modules required for ADFFS to work from being removed.
  Only required for games that RMKill or Unplug Modules.
  No parameter implies ON


*ADFProtectCMOS [ON | OFF]
  Prevents the CMOS from being changed.
  No parameter implies ON


*ADFHideHourglass [ON | OFF]

  Doesn't display an hourglass when loading floppy images.
  No parameter implies ON


*ADFForceVSync <n / 0>

  Ensures a delay of <n> centiseconds between screen buffer swaps, forcing
  a VSync if one hasn't happened since the last frame swap.
  eg. ADFForceVSync 4 would force a game to run at 25 FPS

  Used to either slow downor regulate game speed


*ADFWriteProtect [ON | OFF]

  Prevents writes to the floppy image.
  No parameter implies ON


*ADFEmulateFDC [n]

   Emulate a specific Floppy Controller: 710, 711, 1772
   If no FDC is specified it will reset to the controller in the machine, or
   710/711 if none is present


*ADFReserveMemory <n | 0>

   Reserve <n>KB for the ADFFS floppy buffer.  This is only required when a
   multi-disc game prevents memory being reallocated


*ADFPause <n>
  Pause for <n>ms or until a key or mouse button are pressed


*ADFVoices <n>

  Sets the number of sound channels


*ADFScreenCaching <ON | OFF>

  Turns off screen caching when a StrongARM is present.  For games running
  under the JIT, screen caching can be left on as appropriate cache flushes
  will be performed by the JIT


*ADFRemapVideoMemory [<mode> <size>]

  Remaps video memory to match RISC OS 3.1 and switches emulation to
  RISC OS 3.11 if *ADFEmulateRISCOS hasn't been specified or is currently
  emulating a higher OS version


*ADFEmulateRISCOS [OS version]

  Switches SWI behaviour and sound settings to the RISC OS version specified.
  eg. 3.11 will default sound values to length=208 and Period=48.

  [OS version] can be: Arthur, or the OS version number.
  No parameter turns off OS emulation


*MEMA [B|H|D] <address> <value | "string"> [[B|H|D] [><address>] <value | "string"> .. [<value n>]] [I [<start> <end>]] [| comment]

  Alters memory contents, with DWORD written by default.
  If an address isn't specified by ">address" the next value will be written
  to the next bytes.  When switching from B/H to DWORD care should be taken
  of the alignment.  Use ">address" if required to realign the next address.
  B/H do not need to be aligned to a word boundary.
  Cache flushes are performed as required or forced with "I" with or without
  an address range.  "I" must be the last parameter specified as the cache
  maintenance is performed on return from the command.


*HideCommandWindow

  Prevents "Press SPACE or click mouse to continue" when a script returns to
  the Wimp


*ADFCRC <start> <end> [<crc> [<filename> | <error string>]

  Sets ADFFS$CRC to the CRC value calculated for the specified address range.
  If <crc> is specified an error will be generated if the CRC does not match.
  The error string is defined as::
    No <filename> / <error string>: "CRC does not match"
    <filename> (string with no spaces) : "<filename> does not match the expected file"
    <error string> (string with spaces): "<error string>"


*ADFInsertModule <address> <size>
  Inserts a Module into the RMA


*ADFWimpSlot <min size>[K] [<max size>[K]]
  Mirrors *WimpSlot except it will try to set the allocation to <max size>
  first and only try <min size> if that fails and more memory isn't already
  allocated.  Unlike *WimpSlot the size must be specified in KB
  


Joystick commands
-----------------
*ADFJoystickKeys <[J1 | J2]> [<U | UL | L | DL | D | DR | R | UR | B1-B8>=<keycode> ...] [J2 <U | UL | L | DL | D | DR | R | UR | B1-B8>=<keycode> ...]

  Translates Joystick movement into key presses.  Refer to PRM1-158 or the URL
  below for key numbers


*ADFJoystickMouse [J1 | J2] [damping %] [S=<B1-B8>] [M=<B1-B8>] [A=<B1-B8>] [X=<X offset>] [Y=<Y offset>]

  Translates Joystick movement to the pointer and Joystick buttons to Mouse
  buttons.  When centered, the pointer is positioned at the centre of the
  screen.  Use the X,Y offsets to adjust the relative centre in OS units


*ADFJoystickDeadZone [J1 | J2] <deadzone %>

  Sets the Joystick DeadZone area


Key numbers: "https://www.riscosopen.org/wiki/documentation/show/Low-Level Internal Key Numbers"



MemAlloc
--------
The following commands mirror the MemAlloc module:

*ScreenSize / *SystemSize / *RMASize / *SpriteSize / *FontSize
*RAMFSSize / *RMAFree / *SpriteFree / *FontFree / *RAMFSFree



JIT commands (RISC OS 3.5+)
---------------------------
*GOARM3JIT [[0] | [<address>][;<environment>]]

  Equivalent to *GO, but runs the code as if running on an ARM2 or ARM3
  (ARMv3) depending on the RISC OS version being emulated.  An address of 0
  turns the JIT on but doesn't execute any code.
  If no address is specified the JIT will shutdown.


*GOARM4JIT [[0] | [<address>][;<environment>]]

  Equivalent to *GO, but runs the code as if running on a StrongARM (ARMv4.)
  An address of 0 turns the JIT on, but doesn't execute any code.
  If no address is specified the JIT will shutdown.


*JITMEMORYA [P] <address> <current value> <new value> [<Module title>]

  Replace an instruction at <address> if it matches <current value> when the
  JIT encodes the instruction.  Use "P" to make the change persistent, if it
  needs to be replaced more than once.  If a Module instruction needs
  replacing, <address> is an offset from the start of the Module and the exact
  case-sensitive Module title should be specified


*ADFCACHE [ON | OFF]

  Emulates turning the CPU cache on/off when the JIT is running in ARMv4 mode.
  All translated instructions currently in the JIT instruction cache will be
  cleared and subsequently re-translated


*ADFGO <address>[;environment]

  Equivelent to *GO but will clear flags before calling <address>.  If the JIT
  is enabled, the JIT will start translating and executing code from the
  address



Keys
----
CTRL-SHIFT-F1 thru F9            Change to disc 1..9
CTRL-SHIFT-PAGE UP               Slow game down (add 1cs delay at VSync wait)
CTRL-SHIFT-PAGE DOWN             Speed game up (remove 1cs delay at VSync wait)
CTRL-SHIFT-LEFT ARROW            Mono audio to left channel
CTRL-SHIFT-RIGHT ARROW           Mono audio to right channel
CTRL-SHIFT-DOWN ARROW            Stereo audio
CTRL-SHIFT-F10                   Save floppy image recording file
CTRL-SHIFT-F12                   Quit to desktop (StrongArm and above)
                                 NOTE: This only works for games running
                                       under the JIT



General use Environment variables
---------------------------------
ADFFS$ARMv7             0 - CPU is not ARMv7
                        1 - CPU is ARMv7
ADFFS$Dir                   ADFFS home directory (used as ADFFS:)
ADFFS$CPUID                 CPU ID, values are:
                        2 - ARM2 / 250
                        3 - ARM3
                     &610 - ARM610
                     &620 - ARM620
                     &700 - ARM700
                     &710 - ARM710 / 7500
                     &A10 - StrongARM
                    &xxxx - Later processors will have a 4 digit value
ADFFS$HighVectors       0 - Low Vectors
                        1 - High Vectors
ADFFS$OSVersion             OS version in BCD format.  eg &37100 for 3.71
                            RISC OS 6 will be reported as RISC OS 4.x to
                            allow 32bit OS detection to use >=&50000
ADFFS$VIDC20            0 - No VIDC20 present
                       >0 - VIDC20 address (use: IF ADFFS$VIDC20 THEN ...)
ADFFS$JIT               0 - JIT active or not applicable
                       >0 - JIT active, but the task has been terminated
                            via CTRL-SHIFT-F12.  Use where an obey script
                            runs several tasks in succession
ADFFS$CRC                 - contains the last CRC generated by *ADFCRC
LCDGM$Status           >0 - LCDGameModes is active and using timing set N
                            Use: IF LCDGM$Status=<n> THEN ...



ADFFS SWI's
-----------
ADFFS_Info			593C0 (internal use)

ADFFS_Mount			593C1
  Mount a floppy image, zero terminated

  R0 = pointer to filename

ADFFS_Save			593C2
  Save a mounted floppy back to disc

  R0 = pointer to filename, zero terminated

ADFFS_BootOnWIMPShutdown	593C3 (internal use)

ADFFS_VIDCCR			593C4 (internal use)
  Returns the current VIDC CR in R0

ADFFS_DoNothing			593C5
  Does nothing and returns immediately (internal use)

ADFFS_KeyDebounce		593C6
  Pauses until all keys are released

ADFFS_DiscOp			593C7
  Performs ADFS_DiscOp bypassing ADFFS and going direct to the physical
  floppy drive.  Parameters mirror FileCore_DiscOp

ADFFS_MiscOp			593C8
  Performs ADFS_MiscOp bypassing ADFFS and going direct to the physical
  floppy drive.  Parameters mirror FileCore_MiscOp

ADFFS_Action			593C9
  Action depending on R0

  0 - Allocate buffer
    R1=size

  1 - Mark buffer as mounted/unmounted (internal use)
    R1 = 0 (unmounted)
    R1 = 1 (mounted)

  2 - Extract a file from a ZIP.  Parameters are all zero terminated
    R1 = ZIP filename
    R2 = file to extract
    R3 = filename to extract as

ADFFS_Module			593CA (ARMv4+ build only - internal use)
  OS_Module, bypassing the JIT.  Refer to OS_Module for parameters

ADFFS_Wait			593CB
  Pauses for n ms.  Can be used to add a delay.

  R0 = delay in ms

ADFFS_ShutdownThisTask		593CC (internal use)



!Boot environment variables
---------------------------
ADFFS$FileSizeLimit  max size of file ADFFS will load in KB (2048 max on RO3.1)
ADFFS$LCDGM          Y / N - load LCDGameModes by default (RO 3.1 only)
ADFFS$RecordingPath  default path to save recordings created via ADFRecord



Boot scripts
------------
Boot scripts are run when "Boot floppy" is used from the Filer menu and a
JFD floppy image is mounted.  Scripts should be placed in !ADFFS.obey and
named to match the floppy ID and disc number in the set. eg F1000101 for
2067BC (F10001 - the id and the last two digits denote disk 1)

ADFFS comes with boot scripts for many games that have been tested and/or
officially released, these generally either fix issues with the original
game loaders or add compatibility for later processors and RISCOS versions.

Scripts can be used to launch HD installed games by replacing the contents
of !Run with "ADFBootFloppy Fxxxx01" - where xxxx is the game ID.  The ID can
be found in the JFD imager.



!Boot overrides
---------------
Some games do things they shouldn't in their !Boot, such as auto-launch or
load Modules.  These can be overidden by creating an alternative !Boot under
!ADFFS.override.  The !Boot file should mirror the original, loading icons
and setting up environment variables etc and be placed in an identical
application directory as the original game, under a folder that matches the
floppy ID.  eg for Gribbly's Day Out:

!ADFFS.override.F1017901.!Gribbly.!Boot



Multi-disc support
------------------
ADFFS supports multi-disc software, change the disc via hotkeys:
  CTRL-SHIFT-F1 thru F9

For this to work, the last character of the filename must be the disc
number.  ie "FFTDisc1" / "FFTDisc2" etc



MIME / Transfer of files from PC's / FTPc
-----------------------------------------
When transferring files from a PC via FTPc, it can be useful to add MIME
types for floppy images so the file types are set correctly.  To do this
edit the MimeMap file, which can be found at:
!Boot.Resources.!Internet.files.MimeMap

Add the following MIME definition near the end of the file:

application/adffs	Floppy	FCE	.jfd	.adf	.apd



Caveats
-------
1. RMTidy and RMClear are ignored whilst ADFFS is loaded

2. Uses memory between D00000 to 1000000 on RISC OS 3.1 to
   create a Dynamic area for loading floppy images



Imaging floppy discs as ADF (Amiga Disc Format)
---------------------------

ADF can be used to image unprotected floppy discs and is natively supported by
most Archimedes/RiscPC emulators.

1. Insert the floppy
2. Select "Image floppy\Image as ADF" from the ADFFS Filer
3. Select "Save as" from the ADFFS Filer to save the ADF file



Imaging floppy discs as JFD (JASPP Floppy Disc)
---------------------------

Requirements:  1056KB of free memory to image DD floppies
               1856KB of free memory to image HD floppies

Imaging as JFD has several advantages over ADF, including capturing disc
protection sectors and allowing metadata to be stored within the image.

To image as JFD, a "recording" file of the floppy being imaged is required.
This contains details of the disc geometry used to read the floppy and all
sectors that have been accessed.  ADFFS comes with recording files for most
games, or you may can create your own if required.
The "Creating a JFD file" section below covers imaging use the ADFFS in-built
recording files:


Creating your own recording files
---------------------------------
1. Clean boot the machine (this is to ensure the floppy has not been
   seen by ADFS)
2. Load !ADFFS
3. Press F12
4. *ADFRecord adfs::4.$.Fiiiiidd
   Where:
     iiiii - is the ID (select the title in "Image as JFD" to find the ID)
        dd - is the disc number (eg 01, 02, 03 etc)

   eg Flashback disc 1 would be F1015901

5. Press RETURN to go back to the Desktop
6. Insert the floppy and copy all files to a temporary folder on your
   harddisc or RAM drive.  You may delete them as soon as the copy has
   finished, this step ensures all used sectors are noted
7. If you're imaging disc 1, run the game, once its fully loaded or prompts
   for another disc, press SHIFT-CTRL-F10 to save the recording file.
   For disc 2 onwards, just press SHIFT-CTRL-F10 after copying all the files
8. If you've run the game to image disc 1, reboot the machine


Creating a JFD file
-------------------
1. Select "Image floppy\Image as JFD" from the ADFFS Filer menu
2. Select the title from the drop down, alter any fields as appropriate
   such as the floppy number and filename.  The title list is quite long and
   can be slow to appear on older machines - type the first few characters of
   the game title before opening the menu to reduce the menu size
3. The recording file will be selected automatically if ADFFS has an
   in-built recording of the title/disc in question. If no recording exists
   the imager will default to either "e-format800" or "e-format1600" for the
   recording file.
   If you wish to use your own recording, drag/drop the recording file into
   the imaging window
4. Drag/drop the "Save JFD as" icon to the folder where the JFD file should
   be saved
5. Ensure the floppy is in the drive and click "OK" to start imaging

If you have a unique verson of a game, where you've had to create your own
recording files, please email the JFD files and recordings to: jon@jaspp.org.uk
so they can be added to ADFFS.



Converting APD to JFD
---------------------
APD is a compressed image format that holds complete images of a floppy read
as SD, DD and HD.  Uncompressed they can be quite large and need to be run
through a 1772 emulator whle loading, this can be incredibly slow on early machines.  Converting them to JFD can speed up loading:

1. Open the APD file with ADFFS
2. Select "Save as" from the ADFFS Filer menu and drag the icon to HD, to save
   as a JFD file




Converting Kryoflux recordings
------------------------------

Requirements: Mac or PC with Java 7

1. Download the converter from:
    https://github.com/drdpj/kryotools/

2. Convert the recording to an APD file using the following command:
    java -jar kryo2apd.jar [options] [kryodumpdir]

3. Optionaly convert the APD to JFD as covered in the "Converting APD to JFD"
   section above



Scanning material
-----------------
To help with the archiving effort, please consider submitting scans of games
not currently in the archive.  The current archive state can be viewed at:
    https://forums.jaspp.org.uk/forum/viewtopic.php?t=103

All manual scans shold be 600dpi, box/floppy scans should be
300dpi, scans required are as follows:

1. Both sides of the floppy discs (300 dpi)
2. Manuals, instructions etc.  Ensure all pages are scanned, including
   blank ones (or indicate blank ones), this is to ensure the PDF
   created by JASPP matches the original exactly (600 dpi)
3. Any addition material, such as stickers, posters books, pins.
   Photograph if it's not possible to scan them (300 dpi)
4. For boxes with inserts in plastic sleeves
     4.1 Take the insert out and scan (300 dpi)

   For printed boxes:
     4.2. Scan all sides of the top half (top, bottom, left, right, face)
          If any are identical, scan one and indicate, noting if it's
          flipped vertically.
     4.3. Scan all sides of the bottom of the box, indicating if any
          sides are the same and their rotation.

   For boxes with printing inside the box itself:
     4.4. Scan if possible, photograph if not.

NOTE: You can confirm your scanner is scanning at 300 DPI by checking
      a floppy disc scan is about 1050 x 1050 pixels once cropped



Contributions
-------------
Steve Harrison - LCDGameModes Module, QTMTracker Module and testing
Paul Vernon    - AutoVIDC module and testing
Richard Walker - USBJoystick Module
Jeffrey Lee    - ZLib Module, oddbits code, 4-bit mode conversion code
Michael Drake  - !Sprites file
Darren Salter  - Various hardware for tesing, including an A5000
David Pitt     - Kinetic RiscPC 300 for tesing
Kris Adcock    - Floppies: Elite, Chock Away, SimCity
                 Boxed games: Arcade Games Designer, Games Minipack 3
                 Manuals: Elite, Chock Away
Paul Oates     - Many adventure games from Magnetic Scrolls and TOPOLOGIKA
Fred Graute    - Assistance with fixing Throwback in extASM and additions
                 to StrongEd to aid in coding ADFFS
Xavier Louis Tardy - Iyonix, Eterna originals and various other games



Contact
-------
You can contact myself via the JASPP project: jon@jaspp.org.uk
Or via the JASPP forum: https://forums.jaspp.org.uk