A lua shell for FS-UAE

While FS-UAE recently added a scripting interface with a Lua scripting binding, it only provides capabilities to write scripts with hooks that will be called on certain emulator events. I  hacked this scripting interface and added a Lua remote shell. With this shell you can connect while the emulator is running and issue commands. I also started to add disk image related functions to the Lua binding. With these features combined I could show off the power of a scripting shell by writing a tool to insert floppy and cd-rom disk images while the emulator is running – a long awaited and missing feature…

1. Build FS-UAE with the lua shell

The lua shell is for now only available as a source code patch and you need to compile a fresh FS-UAE to use it. But that is not too difficult:

The code is hosted on the lua branch in my github repository:

https://github.com/cnvogelg/fs-uae/tree/lua

I also submitted the patch as a pull request for the main line FS-UAE  and hope that Frode will like this feature and include it 🙂

Clone this branch and start the compilation with the following options:

$ ./bootstrap
$ mkdir build
$ cd build
$ ../configure --enable-lua

Now you can compile it:

$ make
$ (cd dist/macosx && make)  # only on Mac OS X

This results in a new FS-UAE binary with lua shell support.

2. Configure and First Start

You have to enable the lua shell in order to use it.

Either add an option to one of your .fs-uae config files:

lua_shell = 1

or give the option on the command line:

fs-uae ... --lua_shell=1

The lua shell opens a TCP/IP socket on localhost port 6800 and waits for incoming client connects e.g. via telnet or putty.

You can use the following options to change these settings:

lua_shell_addr = "localhost"
lua_shell_port = 6800

Now launch FS-UAE with the lua shell option enabled and have a look at the log files. They usually reside in Documents/FS-UAE/Cache/Logs/fs-uae.log.txt.

There watch out for messages starting with lua-shell:

$ grep lua-shell ~/Documents/FS-UAE/Cache/Logs/fs-uae.log.txt
lua-shell: addr=127.0.0.1, port=6800
lua-shell: +listener: 20
lua-shell: -listener
lua-shell: stopping done...

If you see these messages you should be able to connect while the emulator is running:

$ telnet 127.0.0.1 6800
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
FS-UAE 2.5.29dev Lua 5.2
>

Ok. Now lets see what you can do in the shell…

3. Using the shell

The lua shell is very similar to the interactive lua interpreter that is shipped with lots of lua distributions (see doc). You can enter a valid lua statement that is then evaluated in the current lua state:

> print "hello, world!"
hello, world!

Note, that the print command is redirected to your shell. Any return value is not printed automatically, you need to prepend a = (or return) before you can enter an expression:

> =2+3
5

Next to most libs that lua already ships the lua shell in FS-UAE also registers special emulator commands for you (see next section for details):

> =fsuae.floppy.get_num_drives()
1

This returns the number of virtual floppy drives that are currently emulated.

If you want to quit the shell then enter the quit() command:

> quit()

You can also simply disconnect the connection by closing with telnet or putty…

3. FS-UAE Lua commands

Currently, the following modules are defined with commands:

  • fsemu – generic emulator commands e.g. for changing display
  • fsuae – commands available in the FS-UAE adaption layer of UAE
  • uae – core Amiga emulator commands, e.g. read Amiga memory

Each module is defined in a lua table with the same name and is thus accessed with this prefix. For an up to date list of commands have a look at the corresponding source files:

  • fsemu in libfsemu/src/emu/emu_lua.c
  • fsuae in src/fs-uae/lualibfsuae.c
  • uae in src/lualibuae.cpp

In this post I’ll focus on the drive image functions I’ve added:

fsuae.floppy.get_num_drives()
  return: the number of floppy drives currently active
fsuae.floppy.set_file(num, path)
  num: index of floppy 0..3
  path: file path of drive image (e.g. adf file)
  return: -
fsuae.floppy.get_file(num)
  num: index of floppy 0..3
  return: file path of current drive image or empty string

The same functions are also available for CD-ROM images: just replace floppy with cdrom in the above commands…

Now you can insert and eject floppy images when you run a lua shell during FS-UAE’s operation:

> fsuae.floppy.set_file(0, "/path/to/my/test.adf")  -- insert image into DF0
> fsuae.floppy.set_file(0, "") -- eject image in DF0

You are now able to control your floppies interactively via shell, but there is more…

4. fs-uae-ctl Command Line Utility

You can also write utility programs that use the shell to communicate with FS-UAE while its running.

fs-uae-ctl found in the new tools directory of the FS-UAE source tree is a small Python 3.x tool that allows to manage the floppy and CD-ROM images via command line:

$ python3 fs-uae-ctl df0 # return the current image attached to DF0
df0 empty
$ python3 fs-uae-ctl df0 /path/to/my/test.adf # insert new image
$ python3 fs-uae-ctl df0 eject # remove current image

Use df1 to df3 to access the other drives (if they are enabled).

Use cd0 to cd3 to access the CD-ROM images.

Some extra options allow you to change the host or port where to find the lua shell. Example:

... --port 6811 --host my.host.ip

5. fs-uae-ctl-ui GUI Image Changer Utility

Of course you could do more fancy and write a GUI based utility. Here it is: fs-uae-ctl-ui also found in tools. It requires PyQt4, so make sure it is installed in your Python 3.x setup. E.g. by installing package python3-pyqt4 on a Ubuntu/Debian Linux system. Mac OS X MaxPorts user install port py34-pyqt4.

If you run the tool, you’ll see a nice image change window:

fs-uae-ctl-ui: FS-UAE Image Changer Utility

fs-uae-ctl-ui: FS-UAE Image Changer Utility

Usage is really simply:

First press button Connect to connect with the running FS-UAE lua shell. If all went well then the enabled drives are also enabled in the UI window. See the status line at the bottom for error messages if any.

On an enabled drive slot you can insert a new disk image by entering a new path name into the edit box. If you press button then a file selector will be opened and allows you to choose a new image to be inserted. Pressing the button with the Eject Symbol ejects the image in the drive slot…

There is also a tab for CD-ROMs with the same feature set.

6. Dev Tools and more…

Both fs-uae-ctl utilities use a common Python 3 library that is also shipped. It allows you to integrate lua shell access to FS-UAE with a few lines of python code and also provides some classes that wrap the floppy and CD-ROM image functions… A high level Emu class wraps everything together:

import fsuae
emu = fsuae.Emu()
if not emu.connect():
  print("ERROR", emu.getError())
else:
  print("Drives", emu.getNumDrives())
  emu.setFloppyImagePath(0,"/path/to/my/test.adf")
  emu.disconnect()

So writing your own tool is not really an issue…

And user jbl007 of the English Amiga Board already picked up the idea while discussing the lua shell (see EAB Thread) and created his own tool that offers the image control in a very compact menu attached to the systray icon of FS-UAE! See his GitHub Repo:

https://github.com/sonnenscheinchen/emu-scripts

His launcher fs-uae.py does all the magic…

(BTW: jbl007 has also written a very nice command line frontend for FS-UE called amiga that allows to run FS-UAE for some standard Amiga models without editing a fs-uae config file. It creates the necessary file automatically during startup…)

That’s it… I hope you enjoy the new lua shell for FS-UAE and if you find new interesting uses of it then drop a comment or join the discussion on EAB…

Leave a Reply