Computing: DOS, OS/2 & Windows Programming

Exotic programming languages for DOS: XPL0.

"XPL0 is essentially a cross between Pascal and C. It looks somewhat like Pascal but works more like C. It was originally created in 1976 by Peter J. R. Boyle, who designed it to run on a 6502 microprocessor as an alternative to BASIC. Although XPL0 stands for eXperimental Programming Language level Zero, it's well beyond the experimental stage and, hopefully, is regarded as well beyond level zero. The name is kept for historical reasons. The language is based on PL/0, Niklaus Wirth's example compiler in his book 'Algorithms + Data Structures = Programs'. Over the years, versions of XPL0 have been ported to many different computers. The programs provided on this site are mostly for IBM-compatible PCs. They all run under DOS, and DOSBox for modern Windows computers."

The paragraph above is how they describe XPL0 on xpl0.org. This tutorial is about the installation of XPL0 3.1 on MS-DOS 6.22. It should also apply to other DOS distributions. Concerning FreeDOS, it might be that you'll have to use the HIMEMX.EXE memory manager (instead of standard JEMMEX.EXE) to make MASM (cf. below) running.

The actual release of XPL0 is version 3.5, with a 32-bit optimizing protected-mode version of the compiler. This release is considered to be lots more powerful than the previous (16-bit) versions. Unfortunately, I did not succeed to use this version on my MS-DOS 6.22 VMware virtual machine. The reason is that the only assembler that version 3.5 supports is TASM, and the TASM linker does not work on VMware. Running it results in the VMware error message A fault has occurred causing a virtual CPU to enter the shutdown state and the VM is rebooted.

XPL0 on MS-DOS 6.22: VMware error when trying to run TLINK

This might be a VMware problem, but it is also possible that the problem is due to TLINK. Just think of the Crt unit of Turbo Pascal, calling one of its functions or procedures resulting in a "divide by zero" error due to not correctly dealing with the modern (high-speed) CPUs. Anyway, I did not try to solve the problem, but decided to install the old XPL0 3.1 version, that beside TASM also supports MASM as assembler. And this works quite well on my MS-DOS 6.22.

Why do we need an assembler, you may ask. The reason is that the build of XPL0 executables requires 3 steps:

  1. The XPL0 compiler converts the XPL0 source code (filename extension .xpl) into assembly code (filename extension .asm).
  2. The assembler (MASM.EXE) converts the assembly code into object code (filename extension .obj).
  3. The linker (LINK.EXE, included with MASM) links the object code to an executable (filename extension .exe).

Installing MASM 5.1.

It's MASM 5.1 that is mentioned on xpl0.org, so I decided to use this version; not to exclude that MASM 6.11 would work correctly with XPL0, too. You can download the software from the Microsoft Macro Assembler 5.x page on the WinWorld website. The download archive contains 5 5.25" 360kB floppy images. Insert Disk01 (MASM) and run RUNME.EXE.

XPL0 on MS-DOS 6.22: Installing MASM - Starting the setup program

The setup program will ask you some questions concerning what to install and where to install it. The screenshot on the left shows some general information, the screenshot on the right shows the selection of the operating system; "dos" is well preselected, so just hit ENTER.

XPL0 on MS-DOS 6.22: Installing MASM - General information
XPL0 on MS-DOS 6.22: Installing MASM - Operating system selection

On the following screens, you are asked for the installation directories. The default directory for the MASM files is c:\masm. I changed the defaults for the executables and include files (c:\bin and c:\include) to c:\masm\bin and c:\masm\include respectively. Please, note that if you use other directories, you'll have to adapt the batch files, described further down in the text accordingly. You may or may not install the Microsoft Editor. This program, called M.EXE, is a full screen editor without menu (also without assembly syntax highlighting), all commands being run using shortcut keys. M is not really easy to work with, if you aren't used to it. The screenshot shows my MASM configuration selections.

XPL0 on MS-DOS 6.22: Installing MASM - Configuration settings

MASM 5.1 is really old software, so no real surprise that the setup program was not able to correctly determine the size of my 2 GB harddisk. Fortunately, it gives the opportunity to ignore that "there is not enough space" to install the software. Setup continues with copying the files. Switch the diskettes when asked to do so. The diskette images included in the WinWorld archive are numbered from 01 to 05; just insert them in that order ("Utilities", the first diskette asked for, corresponding to Disk02).

XPL0 on MS-DOS 6.22: Installing MASM - Ignoring the disk space warning and starting file copy

Finally, the setup program displays the changes that you should make to your CONFIG.SYS and AUTOEXEC. BAT files. Concerning CONFIG.SYS, you'll probably have nothing to change, because the actual settings values are higher than the minima needed by MASM (in my case: BUFFERS=15; FILES=30; /E:800). Concerning AUTOEXEC.BAT, leave it as it is. We will create a batch files that will set the environment variables for MASM.

XPL0 on MS-DOS 6.22: Installing MASM - Propositions for changes in CONFIG.SYS and AUTOEXEC.BAT

Testing the MASM installation.

First, I created the new directory c:\devel\masm for my MASM source files (the executables created by the assembler will be placed there, too):
    mkdir c:\devel
    mkdir c:\devel\masm

Then, I created a custom batch file, called MASMINIT.BAT, that I placed in the directory C:\DOS (directory that is in the executables path). Here is its content (if you used the default or your own install directories, you'll have to adapt the directories!):
    @echo off
    set path=%path%;c:\masm\bin
    set include=c:\masm\include
    set lib=c:\masm\include
    set tmp=c:\temp
    cd \devel\masm

First, the script adds the directory with the MASM executables to the path, then sets the MASM specific environment variables (make sure that C:\TEMP exists; if not, create it), and finally sets the current directory to the directory where I store my source files.

The MASM installation files include a program that may be used to display the content of a text file. The assembly source is called SHOWR.ASM. It is located in the MASM install directory, together with PAGERR.ASM, containing some subroutines called by SHOWR.ASM. I copied these two files to my source files directory:
    cd \masm
    copy showr.asm c:\devel\masm
    copy pagerr.asm c:\devel\masm

Now, we can use MASM.EXE to assemble the two assembly sources. The screenshot below the assembler commands shows the successful assembling of SHOWR.ASM
    masminit
    masm showr.asm
    masm pagerr.asm

XPL0 on MS-DOS 6.22: Testing MASM - Successful assembly of the demo program SHOWR.ASM

MASMINIT.BAT initializes the MASM environment (you need to run it only once...). As the script is located in a directory being part of the executables path, we can launch it from any directory. And as it sets the current directory to c:\devel\masm, where the sources are located, we don't need to specify a path with the assembly file names. The two commands above will create two object files, called SHOWR.OBJ and PAGERR.OBJ (in c:\devel\masm).

To create the executable, we have to link the two object files using the MASM linker LINK.EXE. The screenshots below the linker command show the successful linkage (on the left), and the content of c:\devel\masm, with the executable created SHOWR.EXE.
    link showr.obj pagerr.obj

XPL0 on MS-DOS 6.22: Testing MASM - Successful linkage of the demo program SHOWR
XPL0 on MS-DOS 6.22: Testing MASM - Files created by assembly and linkage of the demo program SHOWR

You can run SHOWR.EXE without parameter; in this case the program asks for a filename. Or, you can specify the text file to display as command line argument. The screenshot shows the display of my CONFIG.SYS.

XPL0 on MS-DOS 6.22: Testing MASM - Successful execution of the demo program SHOWR

Installing XPL0 3.1.

Now we are ready to install XPL0. You can download it from The XPL0 Programming Language website. Be sure to choose the old 16-bit release (XPL0 version 3.1)! The download archive contains the application file system. I unpacked the ZIP file on my Windows 10, and copied the extracted files to a virtual floppy diskette. On the MS-DOS machine, I created the directory c:\cxpl (you should use this name, because most XPL0 examples, that you find on the Internet, use this path in their INCLUDE directives), and copied the content of my diskette to there.
    mkdir c:\cxpl
    cd cxpl
    a:
    copy *.* c:

The screenshot below shows the content of the XPL0 installation directory.

XPL0 on MS-DOS 6.22: The XPL0 3.1 installation directory

Testing the XPL0 installation.

As I said above, the build of an XPL0 source requires 3 steps: compilation, with production of an assembly file; assembly of this file, with creation of an object file; linkage of this object file, with creation of the executable. The XPL0 3.1 installation files include some batch files, that allow to do all 3 steps with one command. Please, note that before you can run these batch file, you'll have to add the directory with the MASM executables to the path:
    set path=c:\dos;c:\masm\bin

Concerning the batch files, lets first view XN.BAT. This script calls the standard compiler XPLNQ.EXE for compilation, MASM.EXE for assembly, and LINK.EXE for linkage. Note that, when running the batch files, you'll have to specify the source file name without file extension! The screenshot below shows the build of GUESS.XPL, a simple game program, included with the installation files.

XPL0 on MS-DOS 6.22: Building GUESS.XPL using the standard compiler XPLNQ

The result of the build is an executable of 17,814 bytes. The screenshot shows it running on my MS-DOS 6.22 virtual machine.

XPL0 on MS-DOS 6.22: Running the executable built from GUESS.XPL

Another batch file included is XX.BAT. It calls the optimizing compiler XPLX.EXE for compilation, MASM.EXE for assembly, and LINK.EXE for linkage. Using this compiler should produce executables that are significantly faster than those created with XPLNQ. The screenshot shows the build of GUESS.XPL.

XPL0 on MS-DOS 6.22: Building GUESS.XPL using the optimizing compiler XPLX

It seems that the executable created with the optimizing compiler is not only faster, but also less in size. In the case of my builds of GUESS.EXE: 14,247 vs 17,814 with the standard compiler.

For programs that do many floating-point calculations running on a computer that has an 80387 math coprocessor (or have a 486DX or Pentium or better CPU), we can make them run much faster by linking in NATIVE7 instead of NATIVE resp. NATIVEX. As there is no reason to not always use this feature, we can make a permanent change in XX.BAT, or, as I did, create a copy of XX.BAT (I called it XPL0.BAT), where we change the linker options. Here is the code of my XPL0.BAT, the changes made in the original XX.BAT being displayed in bold (I commented out the deletion of the assembly file, as it may be interesting to keep the assembly sources created).
    @echo off
    xplx %1
    if errorlevel 1 goto exit
    masm %1;
    link /e/f/packcode/se:512 %1+c:\cxpl\native7;
    rem del %1.asm
    del %1.obj
    :exit

Using NATIVE7 seems further reduce the executable size. In the case of my build of GUESS.EXE, the final executable had a size of 10,720 bytes.

Customizing the XPL0 installation.

First, lets create the directory c:\devel\xpl0 for the XPL0 sources:
    mkdir c:\devel\xpl0

In this directory, lets create a simple "Hello world" program, called HELLO.XPL. Here is the code:
    code Text=12;
    Text(0, "Hello World from XPL0!")

Then, similarly as we did for MASM, lets create a batch file called XPL0INIT.BAT to initialize the XPL0 development environment. Place this file into c:\dos. Located in a directory being part of the executables path, we can launch the script from any directory. Here is the content of my batch file:
    @echo off
    set path=%path%;c:\cxpl;c:\masm\bin
    set include=c:\masm\include;c:\cxpl
    set lib=c:\masm\include
    set tmp=c:\temp
    cd \devel\xpl0

First, we add the directories with the XPL0 and the MASM executables to the path. Then, we set the environment variables for MASM. Important here, that the directory c:\cxpl must be added to the list of include directories. Otherwise, MASM will only search c:\masm\include and will not find the XPL0 runtime; error message: error A2116: Include file not found RUNTIME.ASM. Finally, we set the directory with the XPL0 sources as current directory.

Now, we can build HELLO.XPL by running the commands:
    xpl0init
    xpl0 hello

To note, that xpl0init needs to be run only once. The screenshot shows the successful build.

XPL0 on MS-DOS 6.22: Building a simple 'Hello World' program using custom batch files

XPL0 program samples.

As XPL0 is a barely known programming language, it's rather difficult to find XPL0 documentation and program samples. At the xpl0.org website, you find links to the manual for version 3.1 in PDF format (direct download link: www.xpl0.org/manual.pdf, as well as to a series of simple XPL0 program samples. The site also contains the description and download link (ZIP archive with executable, source, and everything else you need) of a whole bunch of games written in XPL0. Another place, where you can find XPL0 code is the Rosetta Code website. Note that in all examples from this site, you'll have to alter the include of the intrinsics codes to inc c:\cxpl\codesi; ("codes" in the Rosetta Code files).

So, lucky you, you have a programming language, that none of your friends, colleagues, and neighbors has an idea that it exists, running on your DOS machine! Unfortunately, lots of things seem not to work, at least not on my MS-DOS 6.22 VMware virtual machine. For most of the downloaded program samples, that I tried out, either I got some compilation error, or, the build succeeded, but the executable did not start up, making hang the DOS operating system (push CTRL+ALT+DEL to reboot the VM). Why this is so, no idea. Concerning writing my own programs in XPL0, I didn't try ... to many other things to do!

Here is the code of CLOCK.XPL, one of the samples from the xpl0.org/guess.html page. It's interesting, because it shows how to access the DOS API, using interrupt 21.
  inc c:\cxpl\codesi;
  proc NumOut(N);                \output a 2-digit number, including leading zero
    int N;
    begin
      if N <= 9 then ChOut(0, ^0);
      IntOut(0, N);
    end; \NumOut
  proc ShowTime;                 \display current time (e.g: 12:03:45)
    int Reg;
    begin
      Reg:= GetReg;              \get address of array with copy of CPU registers
      Reg(0):= $2C00;            \call DOS function 2C (hex)
      SoftInt($21);              \DOS calls are interrupt 21 (hex)
      NumOut(Reg(2) >> 8);       \the high byte of register CX contains the hours
      ChOut(0, ^:);
      NumOut(Reg(2) & $00FF);    \the low byte of CX contains the minutes
      ChOut(0, ^:);
      NumOut(Reg(3) >> 8);       \the high byte of DX contains the seconds
    end; \ShowTime
  begin \Main
    repeat ChOut(0, $0D);        \carriage return moves to the start of the line
      ShowTime;                  \call routine to show the current time
    until ChkKey;                \keep repeating until a key is struck
  end; \Main

And here is the output of the program (the time shown advancing in real time, of course).

XPL0 on MS-DOS 6.22: Running the sample program CLOCK (from the xpl0.org website)

Another sample from that webpage, that built and executed correctly on my system, is MANDEL.XPL. Here is the screenshot of the program output.

XPL0 on MS-DOS 6.22: Running the sample program MANDEL (from the xpl0.org website)

If you find this text helpful, please, support me and this website by signing my guestbook.