*** DISCLAIMER: The information on these pages is not an official instruction or documentation. No responsibility will be taken. Use at your own risk. ***

Sunday, March 5, 2023

How to prepare a CompactFlash card for Amiga PCMCIA using Linux

An example how to prepare a CompactFlash card for Amiga compactflash.device (cfd) / FAT95 using Linux Fedora Core 33.

The idea is to wipe the CompactFlash card, and create one big partition for Amiga PCMCIA slot use. The procedure should basically be the same on all Linux distributions. Make sure your "mkfs" command has "vfat" support (which it probably has).

0. unplug CompactFlash card device

This makes it easy to identify the card, by plugging it in and watching what happens (see next step).

1. open a shell, log in as root, and watch your system's messages

On Linux Fedora, the system writes messages to /var/log/messages. "tail -f" displays the file's last lines (tail), and updates the output as the file changes ("-f" = "follow").

Watch system messages

2. plug in and identify CompactFlash card device

Plug in your CompactFlash card / reader. The reader used in this example has four slots, with a 1GB CompactFlash card inserted into one of them. As we can see it shows up in the log as drive "sdc".

Find drive name

3. run "fdisk", review and remove existing partitions

This CompactFlash card already has a couple of partitions - we just remove all and start from scratch. In this example, the shell command is "fdisk /dev/sdc" - replace "sdc" with your card(reader)'s drive name from previous step. fdisk's command to print the partition table is "p", and to delete a partition it's "d".

Remove existing partitions (if required/desired)

4. add new partition, set size and file system type

We want to create one big partition for Amiga use. fdisk provides default values for a full size partition, but we leave a little space at the end, in case some emergency-space is required one day. fdisk's command to create a new partition is "a" ("add"). See fdisk's output for size specification.

Add new partition

The new partition has been created with file system type ID 83 / Linux - we have to change that to Windows FAT95.

fdisk's command to set partition type is "t". It automatically selects our only partition (otherwise it would ask for partition number), then asks for new partition type (or "L" to list all types): 

Change partition type

For Amiga's FAT95 filesystem we need partition type "W95 FAT32", which has the Id "b" (or "0b"), as shown by the list of types:

Type Id "b" is for "W95 FAT32"

5. save changes (and reboot)

We're almost done. Enter "p" to print the partition table. It should now show Id "b" and Type "W95 FAT32".

Enter "w" ("write") to save changes.

Review changes, and save

In this example, previously existing partitions on the CompactFlash card were still mounted - see red error messages - so we reboot system with "shutdown -r now".

If your system didn't mount any partitions from your card, then no reboot is required.

Watch your system's messages, re-plug your CompactFlash card (reader), and note its drive name (as in steps 1 and 2) - it probably hasn't changed, just to make sure.

Re-plug and re-check drive name before formatting

6. format new partition as FAT filesystem

Just to make sure we review our partition table before formatting. Run fdisk with your drive's name (example: fdisk /dev/sdc), then enter "p" to print partition table. Note the number of your partition - probably 1. (example: /dev/sdc1, which is number 1.)

Make sure it's the right drive name and partition number

Here's a little optional step that you can safely skip: Activate the partition for booting. The Amiga (compactflash.device / FAT95 / PCMCIA slot) doesn't care, but it might come in handy some day if this CompactFlash card is put into some other machine. fdisk's command to make a partition bootable is "a" ("activate"). Enter "w" to save changes when done. (The new partition wasn't mounted, so changes take effect immediately, no reboot required.)

Optional: make partition bootable (ignored by the Amiga)

Finally, format the new partition with "mkfs" as filesystem type "vfat". Depending on your Linux distro, your mkfs command might look different. On Linux Fedora Core 33 "mkfs.vfat" is available to create a FAT filesystem. On other systems you may have to give command line options (e.g. "mkfs -t vfat ...").

In this example, the full command is: mkfs.vfat /dev/sdc1

Format new partition as type "vfat"

We're done!

To test our newly prepared CompactFlash card, we unplug, and re-insert it. Now the system should auto-mount the new partition.

New partition auto-mounts

This is what it looks like in PCManFM filemanager:

Empty partition in PCManFM filemanager

And here's the information given by "mount", "ls" and "df"

Command line information about the partition

Amiga PCMCIA slot

This is how the CompactFlash card (CF0:) looks from the Amiga side when put into the PCMCIA slot (via adapter) with compactflash.device and FAT95 installed:

Amiga "info" command output


FAT95 filesystem:

(Note: Check for latest versions)

Sunday, March 8, 2020

How do you convert lha to ADF?

The contents of the files are completely different:

  • lha file is a compressed image of one or more files (files, folders)
  • ADF is a raw, fixed size (DD floppy = 880KB) track-by-track image of an AmigaDOS formatted floppy disk (that might, or might not be bootable)

To use the contents of an lha file from an ADF ("convert to ADF"), you have to extract the lha file, and write its contents to an ADF.  
(This implies that the contents of the lha file must fit onto a floppy disk - if they don't, extra work is required, which is beyond the scope of this article.)

You can do so for example by inserting some ADF (preferably a copy, or an empty one!) to your Amiga emulator. Make sure your emulator settings allow for writing to ADF files. Format the disk (ADF) if required, then extract lha to that disk. Example:

> format drive df0: name my_floppy_disk
> lha x myarchive.lha df0:

Note that every good archive - if it contains more than one file - should contain a root folder. Let's assume your archive is a good one, and let's assume the name of the root folder inside the archive is "rootfolder". For your disk (ADF), you probably want the disk itself to be the root folder. So instead of the above steps, directly extracting your lha file to disk, you might want to extract, then copy folder contents. Example:

> format drive df0: name my_floppy_disk
> makedir RAM:adfdir
> lha x myarchive.lha RAM:adfdir
> copy RAM:adfdir/rootfolder/#? df0: all clone

If you're using an emulator, you're done. The contents of your lha archive are now stored in an ADF file. Quit emulator, use ADF as desired.

Using a hardware Amiga with a physical or emulated floppy drive, the procedure is the same, but you'll obviously end up with a floppy disk, not an ADF. You can then use transadf from AmiNet, or any other ADF-reading tool, to create your ADF. Example:

> transadf df0: my_adf.adf

(Here's a floppy emulator that runs on all AmigaOS versions: http://aminet.net/package/disk/misc/fms_20)

To make the disk (ADF) bootable:

Run "install" from a shell. Example:

> install df0:

Then create a text file "s/startup-sequence" that contains the commands to be run on boot - you can use AmigaOS's ed, or any other text editor. Example:

> ed df0:s/startup-sequence

Example: If you want to run "mygame" from folder "myfolder", put this line into the "startup-sequence" file:


Thursday, February 27, 2020

How do I create Amiga-compatible lha archives on other platforms (Linux)?


You've created an lha archive, e.g. on Linux, and your Amiga's lha is unable to decompress it.

Error message: "ERROR on file '...' : Unknown compression"

Possible reason

The lha version used to create the archive is newer than your Amiga's lha version, and/or uses a different default compression method.

You might have obtained your Amiga lha binaries from AmiNet, by downloading the self-extracting lha archive which contains them, and have used these to extract other lha archives from AmiNet.
Depending on when you did so, these binaries might be quite old, and have different options than the lha version you're using e.g. on your Linux machine, including compression method settings.


Manually set lha compression method when creating archive - lh5 will probably the best supported. Here's a quick overview of some lha versions, and the most commonly available compression methods:

Linux "LHa for UNIX version 1.14i-ac20081023":

lha a -o5 filename.lha myfile
      use lh5 compression

lha a -o6 filename.lha myfile
      use lh6 compression

Amiga "LhA Evaluation V1.54 - Copyright (c) 1993 by Stefan Boberg":
(This version does not support lh6 compression.)

lha a -1 filename.lha myfile
      use lh4 compression

lha a -2 filename.lha myfile
      use lh5 compression

Amiga "LhA Freeware Version 2.15":

lha a -2 filename.lha myfile
      use lh5 compression

lha a -3 filename.lha myfile
      use lh6 compression

To check an archive's compression method, use "vv":

lha vv filename.lha

See lha's man page / info / help / version texts for detailed info about more compression options (lh1, lh7, ...).

* * *

Thursday, December 6, 2018

How to set up NFS and mount on Amiga

Here's one way to set up an nfs server under Linux, and mount an nfs share on your Amiga.

Requirements / prerequisites

We're using:

- Linux Fedora 25 or 33 (x86_64 hardware)
Probably any Linux will do, but configuration files and command syntax may differ. NFS must be supported, obviously. We need to be able to set up a NFS v2 server with udp support. This is non-standard on Fedora 25 and 33.

- Amiga 1200
Any Amiga that's able to run AmiTCP3.0b2, and connect to the machine running our Linux, will do.

- TCP/IP connection via AmiTCP3.0b2
We're assuming a working AmiTCP3.0b2 installation, which provides the nfs tools required on the Amiga side, and an active TPC/IP connection to the Linux machine.

In this example we're using IP addresses... for the Amiga and for the Linux box

Our netmask is:

We'll be using a Linux user account called "ami" with UID (user id) 1000 and GID (group id) 1000.

We'll create a user account on the Amiga accordingly ("ami", UID 1000, GID 1000) to avoid access-rights confusion. The Amiga user's home directory will be:


Our nfs share (the Linux directory visible to the Amiga) will be:


This directory - in this case it's the user "ami"'s home directory - should be accessible to the Linux-user "ami", thus it will also be accessible the same way to the (newly created) Amiga-user "ami" via nfs.

In your setup, replace numbers/paths/names with your own values as required.

Linux (IP

Fedora 25's nfs server needs to be "downgraded" to be compatible with AmiTCP3.0b2's nfs tools. nfs version must be 2, and AmiTCP only supports nfs via udp protocol. If udp is not enabled, you will get a RPC error message on the Amiga side.

In Fedora 25, the config file is...


...and the arguments required are:

# Optional arguments passed to rpc.nfsd. See rpc.nfsd(8)
RPCNFSDARGS="-V 2 --udp"

In Fedora 33, the config file is...


...and in section [nfsd] 


...must be set.

Next tell nfs server which directories we want to share with the Amiga or other machines, and who's allowed to access them.

The file...


...contains the setup - use the example below, or add the second line to your file if you already have one. You can see our shared directory, the 10.10.10.xxx range of IP addresses allowed to access it, and our netmask:

/ *(ro,fsid=0)

NOTE: These are two lines, each starting with "/".

You could also use e.g. just, restricting access to this IP address only.

NOTE: Try "man exports" on your Linux machine if you want to know more about the configuration file.

Now we can start (or restart) the nfs server. On Fedora 25 the command is: 

systemctl start nfs-server.service

NOTE: On other Linux systems, you may have to start portmap or rpcbind service first. On Fedora 25 rpcbind.service is enabled by default.

To see if your nfs server is ready enter:

rpcinfo -p

...which will probe and print services registered with the portmapper (see note above). You should see a list roughly like this:

[root@linux]# rpcinfo -p
   program vers proto   port  service
    100000    4   tcp    111  portmapper
    100000    3   tcp    111  portmapper
    100000    2   tcp    111  portmapper
    100000    4   udp    111  portmapper
    100000    3   udp    111  portmapper
    100000    2   udp    111  portmapper
    100024    1   udp  38814  status
    100024    1   tcp  53319  status
    100005    1   udp  20048  mountd
    100005    1   tcp  20048  mountd
    100005    2   udp  20048  mountd
    100005    2   tcp  20048  mountd
    100005    3   udp  20048  mountd
    100005    3   tcp  20048  mountd
    100003    2   tcp   2049  nfs
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    2   tcp   2049  nfs_acl
    100227    3   tcp   2049  nfs_acl
    100003    2   udp   2049  nfs
    100003    3   udp   2049  nfs
    100227    2   udp   2049  nfs_acl
    100227    3   udp   2049  nfs_acl
    100021    1   udp  39239  nlockmgr
    100021    3   udp  39239  nlockmgr
    100021    4   udp  39239  nlockmgr
    100021    1   tcp  33909  nlockmgr
    100021    3   tcp  33909  nlockmgr
    100021    4   tcp  33909  nlockmgr

The important lines are the ones with a "2" in the "vers" = "version column. Remember configuring nfs server for version-2 support?
We need a version-2 portmapper supporting udp (line 6), same for mountd (line 11), nfs (line 15), and nfs_acl (line 18).

If you got this far without errors, you're done with the Linux part.

For setup/testing it's probably best to make sure your Linux's firewall is off. You can examine network traffic/ports and adjust your firewall settings later.

Amiga (IP

Now we can partly test the setup from the Amiga side using "rpcinfo", which comes with AmiTCP3.0b2:

rpcinfo -p

This should give you the same list as on the Linux side. (See above.)

NOTE: Output syntax may differ slightly - service names (rightmost column) might be missing.

We need to specify a user account on the Amiga side. For a proper setup it should match the Linux user "ami"'s UID and GID (see "Requirements / prerequisites" above).

NOTE: The user's name is actually not relevant to nfs, but for simplicity and clearness we also call it "ami", just like the Linux one.

Before creating an Amiga user for AmiTCP, we first create a home directory for him/her:

makedir Work:home/ami

Next, create the user account. Edit the file...


...and add a line that looks like this:

ami|*|1000|1000|Amiga 1200|Work:home/ami|shell

Separated by pipes ("|"), these are...
...user name
...password ("*" = empty)
...UID (user id)
...GID (group id)
...real name
...home directory
...login shell command

NOTE: Try "man 5 passwd" on Fedora 25 for an explanation of the password-file. (Linux uses colons instead of pipes here.)

Probably not required, but it's always good to set a password for a user - do so by entering:

AmiTCP:bin/passwd ami

...and enter your desired password. (Twice.)

NOTE: Now your AmiTCP:db/passwd file contains an encrypted password instead of an asterisk in the password-field for user "ami".

Next set up the nfs share (directory) for the Amiga - to do so, we edit the file...


...and add this line: NFS: user ami umask 0755

As you can see there's our Linux's IP address, and the shared Linux directory.
Next is the local (Amiga) name for the share ("NFS:"), with a trailing colon, just like a logical drive ("assign") on the Amiga. Finally the user account we want to use, and a umask, defining which access-rights a file written to the share will have.

NOTE: "0755" basically means: owner can read, write (also delete), and execute file, others can just read and execute. Here's an extensive explanation of Linux file permissions: https://help.ubuntu.com/community/FilePermissions

And here cometh the moment of truth!

Finally, to mount your nfs share on your Amiga, enter this:

AmiTCP:bin/ch_nfsmount nfs: 

NOTE: Needs stacksize > 30000. You will get an error message if it's insufficient. Use e.g. "stack 100000" to set it to 100000.

As you can see the argument to "ch_nfsmount" is our local nfs share name "nfs:". (AmigaDOS is not case sensitive.)

A disk icon named "NFS" should pop up on your workbench, and you're ready to use your Linux's directory from your Amiga! 


Network debugging etc. is very limited on the Amiga:

Test your TCP/IP network connection:


List your Linux's registered RPC services from the Amiga side:

rpcinfo -p

Linux has some powerful network debugging tools:

You can switch on kernel debugging modules, then watch your Linux log files (syslog, kernel log) for output:

rpcdebug -m nfsd -s all rpcdebug -m rpc -s all

NOTE: This sets all debug flags for modules "nfsd" and "rpc", enabling debug logging. To clear use "-c" instead of "-s".

"wireshark" is a powerful network traffic analyzing tool, that allows to capture, and view network traffic in full detail.


  • Your mileage may vary. There are a couple of bugs and instabilities along the way. Don't be too harsh with nfs on the Amiga. If in doubt reset and retry. (See next note, too.)
  • An update to the nfs tools provided with AmiTCP 3.0b2 is available on AmiNet, including docs: http://aminet.net/package/comm/net/chnfsc102-30b2
  • AmiTCP is known for it's extensive documentation. Read the docs for general TCP/IP information, and details about AmiTCP's components.
  • Your Linux most likely contains man-pages on the network commands and configuration files used here. The commands provided with AmiTCP 3.0b2 are more or less compatible.
  • Special thanks to Markus "Tulpi" T. for massive technical and moral support!


2021-03-18: added Linux Fedora 33 information

Saturday, September 30, 2017

how do I get rid of the "Ebola" virus?

Possible symptoms:
executable file size grows by 1116 bytes after run.

Possible reasons:
- system infected with Ebola virus

Possible solutions:
- remove Ebola virus:
  1. get antivirus software (e.g. VirusZ or VirusExecutor) from http://www.vht-dk.dk/ or from AmiNet: http://aminet.net/search?query=virus
  2. put antivirus on some media that can be mounted from shell
  3. have a write-protected, virus-free workbench bootdisk*
  4. boot from write-protected, virus-free workbench bootdisk, mount media with antivirus software as required
  5. run antivirus software, scan all drives / files, hit "repair file" or "remove virus" as indicated by antivirus software ("Ebola" can be removed successfully. May fail on OS3.9 "SetPatch", though. Replace bad file with good one from original installation media, if required.)
  6. run HDToolbox, check every partition of harddisc for RDB's installed filesystem: go to "Advanced options..." -> "Filesystem..." -> "Change/Update..." and compare size of installed filesystem with filesystem on disk (now scanned/cleaned). Re-Install filesystem from disk, if it's 1116 bytes smaller than the one installed in RDB. (Keep in mind AmigaOS versions: compare filesystems of equal versions.)
  7. switch off Amiga and let rest for at least 30 seconds
*) not strictly required, but may avoid multiple de-contamination runs/reboots

Tuesday, August 15, 2017

why does vbcc's printf()/snprintf()... not respect %f in format strings?

using printf("%f", 1.2);
instead of

Possible reasons:
no math lib included

Possible solutions:
- add -lmieee or -lmsoft (or other math library -> see vbcc manual) to list of compiler options
- put -lmieee (or whatever math lib you're using) before -lvc in list of compiler libs options

Saturday, August 12, 2017

how do I properly read user input using a AmigaDOS script?

- user input handling via "ask" isn't sufficient
- empty user input (empty string, user just hit return) can't be checked

Possible solution:

this is an example AmigaDOS script asking user for an ip address, and using a default value if user just hits return:

; default value:
set DEF_IP

; message to user, including default value:
echo "please enter your IP address (default: ${DEF_IP}):"

; unset variable before use, for proper testing afterwards:
unset IP

; read user input into variable.
; if user just hits return, variable doesn't get set.
set >nil: IP ?

; get variable, suppress output:
get >nil: IP

; if there was an error, it means variable hasn't been set.

    ; use default value if there was an error
    set IP ${DEF_IP}

; print result (default value, or user input)
echo "using IP address: ${IP}"