December Adventure Day 16

    Emulators Galore

    Having made good progress writing a lightweight Psion emulator launcher on day 15 of my December Adventure, I decided to continue with it, flesh out the device support, and add a few quality-of-life improvements.

    psiemu

    As an active contributor to the explit28/Psion-ROM repository on GitHub, I’m aware of the large number of Psion variants out there, but I’d not fully internalized it until I tried to produce a UI to make it quick and easy to see them all, and select one.

    After some consideration, I decided to separate the different vendors into their own sections, with Psion and Acorn being the most obvious ones. Ultimately, I’d like to add Geofox, Diamond, Oregon Scientific and Ericsson in there too, but I don’t think we’ve complete emulation for any of their devices yet.

    Modeling the ‘Vendor → Device → Variant’ hierarchy

    Introducing new sections forced me to rework the layout and selection handling. To keep things simple, I broke my rendering code into helpers responsible for the different sections. For example,

    def render_device_section(devices, is_section_active, y_pos, selection):
    
        for device_index, profile in enumerate(devices):
            title = profile["title"].ljust(22)
            variants = profile["variants"]
    
            for variant_index, variant in enumerate(variants):
                name = variant["name"]
                languages = language_symbol(variant)
                if is_section_active and device_index == selection.device and variant_index == selection.variant:
                    name = "-> " + name
                else:
                    name = "   " + name
                title += f"{name} {languages}  "
    
            stdscr.addstr(y_pos + device_index, 0, "  " + title)
    
        return y_pos + len(devices)
    

    This renders vendor data in the following structure:

        {
            "name": "Acorn",
            "devices": [
    
                {
                    "id": "pocketbk",
                    "title": "Acorn Pocket Book",
                    "resolution": (240, 80),
                    "scale": 2,
                    "variants": [
                        {
                            "name": "V1.91F",
                            "bios": "191f",
                            "languages": [
                                "en-GB",
                            ],
                        }
                    ]
                },
    
                # ...
                
            ],
        },
    

    Right now the layout code is all hand-crafted as I’m fairly new to Curses, but I have a sense there are many conveniences I can take advantage of in the future. I’m looking forward to learning what’s possible.

    In addition to adding support for different vendors, I decided to lean more on structured data, starting with supported languages (as shown in the example above). Using metadata like this should allow for richer UI in the future, and I experimented with using emoji as a minimal way to display the languages:

    Ultimately, I find the additional color distracts me from the other details in the grid, so I’ve decided not to keep them, but I enjoyed seeing what’s possible.

    As I progressed through the day, I added more devices and variants to the launcher, making sure the relevant ROMs were present in the explit28/Psion-ROM repository. My hope is that this can serve as a single source for all preserved Psion and Psion-related firmware. The MAME emulators are a good test for that.

    Wrapping up, I created a new repository on Codeberg and pushed what I have. Nascent as it is, it’s nice to get the launcher to a point where I’m happy to share it and invite collaboration.

    The day ended on a high when Alex shared a screenshot of it running. 🥳

    December Adventure Day 15

    Psion Emulation and Python Curses

    Day 15 of my December Adventure started with a request from Tom for some Psion Series 3 assets for OpoLua. Since I don’t have a Series 3 to hand here in Hawai'i, this seemed like the perfect excuse to remind myself how to fire-up an emulator using MAME and focus on, ‘write about MAME emulation’, from my original list of adventuring possibilities.

    Psion Emulation

    MAME includes many Psion hardware and language variants

    The Psion emulation story in MAME is really impressive, but I don’t find the MAME launcher works well for standalone computers—it’s really designed for launching individual games. Instead, I run specific emulators from the command line. For example, I launch the Series 3a emulator as follows:

    mame \
        -window \
        -nomaximize \
        -skip_gameinfo \
        -rompath ~/Software/Psion/ROMs \
        -prescale 2 \
        -resolution 960x320 \
        psion3a
    

    There’s a few notable options in there which—in my opinion—really help the Psion emulation shine:

    • -skip_ganeminfo—don’t show unnecessary dialogs
    • -nomaximize—run in windowed mode—I prefer this as the Psions have fairly unusual aspect resolutions
    • -prescale 2—enable pixel-doubling for high-resolution displays
    • -resolution 960x320—coupled with pixel-doubling, this ensures the emulation displays at exactly 2x for crisp pixels

    There’s also some useful keyboard shortcuts to be aware of. These vary from device to device. For the Series 3a, they look like this:

    Device Key Shortcut
    On (Esc) Esc
    Off (Psion + Esc) Alt (Opt on macOS) + 1
    Psion Alt (Opt on macOS)
    Help F10
    Menu F11 (Shift + F11 on macOS)
    System F1
    Data F2
    Word F3
    Agenda F4
    Time F5
    World F6
    Calc F7
    Sheet F8

    A Custom Launcher

    Needless to say, I find myself looking up the MAME command line and keyboard shortcuts every time I need to use an emulator. I’ve written a number of shell scripts and aliases to help1, but there are so many device variants that this approach gets unwieldy pretty. Finding ROMs can also be challenging—most are available in explit28/Psion-ROM where we’re trying to dump, document, and preserve everything we can find, but it’s currently incomplete.

    With that in mind, I decided to finally bite the bullet and start writing my own launcher. The goal here is to clearly present all the different device types and variants to help folks see what’s available. I’d also like to add support for automatically downloading ROMs in the future.

    I’m using Python and Curses to create this to ensure I’ve something instantly cross-platform, as I know most of the Psion community choose to use Linux.

    It’s been a really fun experience so far, playing around with writing an interactive terminal UI and seeing future possibilities. I’ve opted for a grid-layout to show devices and variants2, and I’ve realized I can add contextual footers showing additional device details and, ultimately, interactive pickers for configuring attached SSDs, serial ports, etc.

    I hope to publish this nascent launcher over the coming days. 🚀


    1. If you’re using Linux, you can also create desktop entries for quickly launching each Psion emulators. 

      For example, to create a local Series 3a desktop entry, create .local/share/applications/psion-series-3a.desktop containing something like:

        [Desktop Entry]
      
        Type=Application
        Version=1.0
        Name=Psion Series 3a
        Path=/home/parallels
        Exec=/usr/bin/mame -window -nomaximize -skip_gameinfo -rompath /home/parallels/Software/Psion/ROMs -prescale 2 -resolution 960x320 psion3a
        Terminal=false
      
    2. Perhaps I was influenced by Matt Sephton’s notes on using spreadsheets for UI design

    December Adventure Day 14

    Photographic Dependencies

    I’m trying to stick to daily write-ups of my December Adventure, meaning that I write about the less exciting days, as well as the more exciting ones. Day 14 falls firmly in latter camp.

    I had hoped to hit the ground running by reinforcing the hinges of my Psion Series 3a with JB Weld, and later carefully opening my Toshiba Libretto 50CTs to remove their (hopefully non-leaky) backup batteries. Instead day 13’s write-up proved a slow one, and then I found myself trapped, deliberating how to photograph and film these tasks so I can document them.

    I have been experimenting with a (very flimsy) lightweight tripod and my iPhone to capture top-down photos with very little success: the camera slowly sinks as the tripod really isn’t designed for this orientation; it’s hard to get good lighting; and the iPhone’s automatic exposure and magic colour-correction means images vary wildly. It’s also hard to keep the whole plane in focus when doing closeup work. (This really isn’t my area of expertise.)

    The iPhone makes it incredibly challenging to maintain consistent exposure and color temperature

    As I find myself working more and more on physical projects, I’d love to come up with a setup that I don’t need to think about. I plan to try Halide over the next few days in the hope that this will give me more control, and I’ve been noodling on a seemingly TikTok-focused tripod that’s essentially an anglepoise arm with a phone mount and ring light. Perhaps I can get into retro unboxings. 📦🙃

    Amazon—🤢—sells near-identical social media ‘desk tripods’ by a seemingly infinite number of brands