Ariel Personal Computer

June 10, 2021Ariel

When I was a teenager, I only had access to a Commodore 64 at home. I envied my friends who had a PC or even an Amiga, for the seemingly unlimited RAM and crisp high resolution text display. Glorious 80 columns! At one point I wrote a Bash-like shell on my C64 with 80 character software display, each character had to fit into 4*8 pixels. It looked surprisingly good on my monochrome monitor, considering, but it was slow and I barely had any RAM left for programs to load due to all the space the shell functionality used up.

Later I got an Amiga 500 and I was happy with it text-wise, it could display a proper 640*200 screen with 80 columns of text. It was great for logging into a remote server via telnet using a modem (back then it wasn't considered harmful) where I had an account and I could use email and IRC. Writing assembly and C code on the Amiga was great and I had 1 MB RAM in it, which felt like tons. I nurtured a dream for years that I would get an Amiga 1200 with a hard disk in it and I could write a whole OS for it in assembly. The dream was never realized. When I got a proper PC I was writing programs in C; making an OS didn't seem plausible due to the complexity of the CPU and the hardware itself. Sure I wrote some assembly code with BIOS interrupt calls but making anything serious as bare metal code is pretty hard on a PC. Especially these days.

A few years ago I thought the Raspberry Pi will be great for such aspirations, but while the ARM CPU itself is OK to code for, the hardware is just way too modern, and in the same time surprisingly badly documented. Sure, making the Status LED blink was doable, but even that has sailed with the Pi 4 as I heard. Putting text on the screen is hard due to working in graphics mode (good luck even making a frame buffer with all those badly documented mail slots), accessing the SD card is hard, writing a whole Fat32 file system driver is hard, writing a USB driver for keyboard handling is super hard. Using the GPIO pins to access the Pi via serial port is doable, but then you are still just using a terminal program to access a box, and for every change in the kernel code you need to copy data to the SD card and reboot, or use QEMU for everything, and... Small wonder that most "Let's make an OS on ARM" projects die at the stage of a blinking LED.

Some dreams come true

My dream computer would use a 32-bit CPU that is similar to ARM, but less complicated to work with, so it's somewhere between the 6502 and the ARM V6. Lots of RAM, up to 4 GB due to the 32-bit address space, but realistically I would never need that much. Easy enough access to the hardware using Hardware I/O registers. Unified memory architecture if I would ever have video and audio in it. A smart disk controller device that would give access to the file system in a high level way, so its firmware would handle the complicated block level tasks. A serial console port solution to access the system using a terminal program.

Since nobody is going to make it for me, and I'm just a software guy, I decided to make my own computer as a virtualized entity. It's called Ariel.

I created a small Virtual Machine in C# that can run a RISC CPU I designed and some virtual hardware devices I made. The ARM-like CPU is something that would work in real life, it could be implemented as an FPGA core, and the devices are either realistic or plausible. The VM can run code over 12 MIPS (million instructions per second) on my PC; this is comparable to a speedy Intel 486. Plenty of power for my needs, I would be fine with just 1 MIPS, and it's not particularly optimized code. Also this is just a number, I believe the Ariel CPU packs a bigger punch than a 486 when it needs to run useful code.

I wrote my own assembler for it, along with a Visual Studio Code extension. It works like a charm, in some aspects it's even better than Retro Assembler. Ariel boots a ROM image that is really simple so far, and afterwards the ROM will load the Kernel from the file system. The RAM size is configurable, it can be up to 4095 MB. The top 1 MB is the Hardware Space, and the top 64 KB is the Hardware I/O Space for the hardware registers that give me access to the devices. The VM emulates the serial console port using a TCP Socket, so I can connect to it via Telnet on a specific port, even via the Internet.

What is it good for?

If you're interested in this project, and would like to try it later, and perhaps even would like to write some code for Ariel, let me know what you think on Twitter. I would appreciate it. I'll follow up on how this project is going when there's more to share.

Retro Assembler V2021.1 Released

January 1, 2021Retro Assembler

Now that we reached a new year and Microsoft is consolidating .NET Core and the .NET Framework into a merged version, Retro Assembler is now built for .NET 5.0

After you install it on Windows, macOS or Linux, you can run the assembler just like you did before. Or if you're new to it, check out Using Retro Assembler with Visual Studio Code for some additional guidance.

If you've been following the MEGA65 development in the past few years, you might be as excited as I am that it will be available for purchase soon. Quite possibly, maybe. But now that at least some lucky people laid their hands on the limited developer version, you may find it useful that Retro Assembler got support for the MEGA65 45GS02 and the plain CSC 4510 CPUs. Nothing can stop you now from developing for the MEGA65!

Beside this I attempted to standardize the 65816 source code a bit, so in instructions that use the Stack Pointer, the assembler accepts both SP and S as register name. The disassembler now shows SP.

The Notepad++ language files and the Visual Studio Code Extension got support for the new CPUs and for the SP register.

See the documentation for details.

Download the latest version from the Retro Assembler page!

How to Install .NET on Linux and macOS

Updated on January 12, 2021Retro Assembler.NETLinux

If you want to use Retro Assembler to code on Linux (even on a Raspberry Pi) or on macOS, you have to install .NET on your computer. The current version is .NET 5.0 This used to be called .NET Core in previous versions, but Retro Assembler doesn't support those anymore. Normally you'd just go to and follow the instructions, but if you need help, I'll try to provide some here. Especially for ARM-based single board computers, see below.


Installing on Windows

Installing on macOS

Installing on Linux

Here are the commands you'll need to enter into the Terminal:

#Download the Ubuntu 20.10 related packages for the package manager.
wget -O packages-microsoft-prod.deb

#Install it for the package manager.
sudo dpkg -i packages-microsoft-prod.deb

#Update the package manager.
sudo apt-get update

#Install this utility.
sudo apt-get install apt-transport-https

#Update the package manager (again).
sudo apt-get update

#Install the .NET Runtime.
sudo apt-get install dotnet-runtime-5.0

#Alternatively, Install the full .NET SDK
sudo apt-get install dotnet-sdk-5.0

Installing on Raspberry Pi and on other ARM based SBCs

Here are the commands you'll need to enter into the Terminal:

#Install some possibly missing packages that will be needed.
sudo apt-get install libunwind8 gettext curl wget

#Make the dotnet directory where the .NET Runtime will be installed.
sudo mkdir /usr/share/dotnet

#Extract the files from the downloaded file.
sudo tar -xvf dotnet.tar.gz -C /usr/share/dotnet/

#Set up a symbolic link to this directory so it will be found on path
#when you type in the command "dotnet".
sudo ln -s /usr/share/dotnet/dotnet /usr/local/bin

This works perfectly, the only caveat is that you'll need to perform this manual install with every updated .NET version you want to use.

Testing in the Terminal

Run this command to check whether the .NET Runtime has been installed successfully. It will list the currently installed version's details.

dotnet --info

Now you can run Retro Assembler with this command:

dotnet retroassembler.dll

Optional, but it is recommended to edit the command shell's startup file with a command alias to run Retro Assembler with ease, as if it was a Linux/Mac native command line application.

Open your user's home directory and edit the hidden file .bashrc on Linux, or .bash_profile on macOS. The latter usually doesn't exist and you have to create it. Then enter this line into the bash file with your chosen file path:

alias ra='dotnet ~/PATH/retroassembler.dll'

This will allow you to just enter the command ra and run the assembler from either the Terminal or from Visual Studio Code.

Retro Assembler V2020.12 Released

June 16, 2020Retro Assembler

The following updates have been made:

Empty Macros get removed from the compiled code automatically. These caused some local label issues.

When the Setting OmitUnusedFunctions is Enabled, empty Functions and their standard, correctly formatted calls get removed from the compiled code.

When the Setting Debug is Enabled, a text representation of the compiled code is saved alongside with the normal debug information. This way you can check out your compiled file's code and data contents, without doing Disassembling which would not recognize the data sections. You can change its default filename in the Setting DebugCodeFile or in the Settings Xml file.

When the Setting OutputSaveInfoFile is Enabled, now Atari DOS (.xex) files create the Info file about memory usage. The Atari 800 example file has been updated to utilize this feature.

See the documentation for details.

Download the latest version from the Retro Assembler page!

Retro Assembler V2020.11 Released

June 11, 2020Retro Assembler

This is a quick update for to fix a nasty little bug in the parser and compiler.

The problem was with the number size detection of currently-undefined labels. An lda <Label or lda >Label instruction, or similar ones using a zero page address would process the memory address of Label incorrectly, when Label is defined after the instruction's code line.

Friend of the project, John Tsombakos was kind enough to write up a reproduction case about it. Thank you John!

See the documentation for details.

Download the latest version from the Retro Assembler page!

Retro Assembler V2020.10 Released

May 29, 2020Retro Assembler

The following changes have been made since the last update:

See the documentation for details.

Download the latest version from the Retro Assembler page!

Retro Assembler V2020.9 Released

May 17, 2020Retro Assembler

There was a serious bug in the Long Branch handler, it has been fixed.

I also added ATASCII (Atari ASCII) and ScreencodeAtari support in the .encoding directive. ATASCII is pretty much the same as normal ASCII, but certain control characters use different byte values.

See the documentation for details.

Download the latest version from the Retro Assembler page!

Retro Assembler V2020.8 Released

May 16, 2020Retro Assembler

I seem to be on the roll these days. My friend Josh at Gang-Gang Studios (who is working on a truly amazing game) asked whether Functions could work similarly to Macros – they won't get included if they are not referenced by the source code itself. I've been wondering about the same recently and it seems like I managed to come up with a good solution to this. It wasn't easy, had a bit of an Edison moment with the thousand ways you can't make a light bulb, but at the end it worked out.

There is a new Setting "OmitUnusedFunctions" for this, which is enabled by default. If your code requires a behavior where all functions are compiled into the binary, you can disable it in your code or in the Settings Xml file.

I also added a new default Segment called Lib (short for Library), which got its .lib shortcut directive. This is placed between the Code and Data Segments, so if you have a large library you need to include, you can utilize this Segment to separate the Functions from the Code Segment's contents. Of course this is optional, or you can use a custom Segment for this purpose.

See the documentation for details.

Download the latest version from the Retro Assembler page!

Retro Assembler V2020.7 Released

May 13, 2020Retro Assembler

In this new update I added a couple of new features:

I added a new directive .format to replace the old .setting "OutputFormat" solution. It's strange I haven't done this sooner, but now it's here.

I added a new Setting HandleLongBranch. The instructions that use relative addressing, typically branching instructions like bne or beq can only handle a certain address range, especially on 8-bit CPUs. When this range is exceeded, the assembler shows an error message about it. If you enable this setting, the assembler tries to resolve these errors by automatically replacing the generated code with a counterpart that can handle long jumps to absolute addresses.

Label  nop
(Lots of instructions here, over $80 bytes worth)
bne Label
(Other instructions)

This fails because Label is way too far away for a relative address jump. The assembler will compile this instead:

Label  nop
(Lots of instructions here, over $80 bytes worth)
beq AfterJmp  //Branch counterpart for "bne"
jmp Label     //Jump to an absolute address.
AfterJmp      //The label that's accessible as a short relative jump.
(Other instructions)

It's handled like this on 6502, 65C02 and 65816, with all the branch instructions of these CPUs. On Z80 and Gameboy CPUs the case is simpler, the jr instructions get replaced with the appropriate jp instructions.

Of course this is not ideal if your goal is writing code that can be relocated to any memory address, but that's rare and then you surely know what you are doing. The feature is not turned on by default, but if you need it, and most people likely would, it can be enabled, even for just a section of the code, by .setting "HandleLongBranch", true

The rest of the changes can be filed under Good Housekeeping:

See the documentation for details.

Download the latest version from the Retro Assembler page!

Retro Assembler V2020.6 Released

May 9, 2020Retro Assembler

In this update I added a new .namespace directive, which can create and use user-defined Namespaces for Labels. If your project and workflow finds a use for it, you're in luck. It can be really powerful in the right hands, but it's probably unnecessary for most coders.

The VS Code Extension and the Notepad++ files have been updated to recognize this new directive.

The .generate directive got a new "random" mode to add an array of one or more random bytes.

The Atari DOS files with the .xex extension are now loaded and processed by the Disassembler as Atari DOS would, by processing each Chunk of data and loading them at the correct memory addresses. The Launcher Chunk is ignored by the loader, otherwise those files would be listed from $02e0

For developers who need to integrate Retro Assembler into a .Net Core project, the retroassembler.dll file offers a few Compiler functions that can be useful in unit tests.

See the documentation for details.

Download the latest version from the Retro Assembler page!

Check out the Archive for more posts!