Skip to main content

Raymii.org Raymii.org Logo

Quis custodiet ipsos custodes?
Home | About | All pages | Cluster Status | RSS Feed

Compiling TETRIS from 1992 on OpenVMS x86 in 2024!

Published: 18-08-2024 14:33 | Author: Remy van Elst | Text only version of this article



Since DECWindows / CDE now works on OpenVMS x86 (from 9.2-3 onwards) there is much fun stuff to do. Back in 2021 I wrote an article on the CDE desktop on Alpha / AXPbox and also an article on how to run CDE on modern linux, since it's still developed. Both articles included a game, GENERIC-TETRIS from 1992, written by Qiang Alex Zhao. After getting the (remote) desktop working I wanted to compile and run Tetris to continue this lineage, from VAX, to Alpha, to Linux/CDE, to x86 VMS. I haven't got an Itanium to run it on, but if anyone has one left willing to send this way, feel free to contact me. This article includes the precompiled tetris binary for OpenVMS x86 and instructions to compile the source. The code required some minor modifications which I'll also cover, but that's not surprising for code that hasn't changed much since 1992 to be compiled in 2024. This article also shows you how to install curl on OpenVMS.

Recently I removed all Google Ads from this site due to their invasive tracking, as well as Google Analytics. Please, if you found this content useful, consider a small donation using any of the options below:

I'm developing an open source monitoring app called Leaf Node Monitoring, for windows, linux & android. Go check it out!

Consider sponsoring me on Github. It means the world to me if you show your appreciation and you'll help pay the server costs.

You can also sponsor me by getting a Digital Ocean VPS. With this referral link you'll get $200 credit for 60 days. Spend $25 after your credit expires and I'll get $25!

You can read all my OpenVMS articles here.

tetris on x86 openvms

Here is Tetris running on OpenVMS 9.2-3 for x86!

You do need to find a way to download OpenVMS E9.2-3. You can either apply to the Ambassador Program or wait until the Hobbyist License Virtual Machine is updated, or, be a paying customer. The Hobbyist virtual machine includes the C and C++ compiler and the precompiled binary might work. Give it a try and let me know!

Follow along and have some compile fun!

You can download my compiled tetris for OpenVMS x86 binary here.

Make sure to have the desktop up and running. Open the file manager, navigate to the folder where you've placed the binary and click it. Have fun playing!

If you want to follow along with compiling, download the sources for Tetris here.

I assume that you have a (virtual) machine setup with OpenVMS for the rest of this article. I'm using the SYSTEM user. SSH access is available by default on these new releases of OpenVMS so you can login with Putty or your favorite SSH client of choice without any setup hassle.

Create ISO for file transfer

I had some issues with my friendly local FTP server so I choose to use a VirtualBox feature to transfer the installation files and sources over to my OpenVMS Virtual Machine via an ISO. Virtualbox lets you select files and then automatically makes a (sort of transient) ISO image and couples that. You can also use FTP or if you have it installed, curl.

virtualbox iso

I also added the C and C++ compiler installers and curl. The pre-built hobbyist VM comes with the C compiler included, but if you don't have that yet, I used X86VMS-C-X0706-004-1 (VSI NATIVE C Compiler X7.6-004-1 for OpenVMS X86 Version V9.2-1 and later).

Finish the ISO wizard and make sure it is attached in Virtualbox to your OpenVMS VM.

Mount ISO in OpenVMS

This is a brief summary, if you want to find out more about the quirks on mounting an ISO on OpenVMS, check out my earlier article.

If needed, change your device name (show devices for more info) from DKA0 to your CD-ROM drive. Mount the disk:

mount /override=ident dka0

Output:

%MOUNT-I-WRITELOCK, volume is write locked
%MOUNT-I-CDROM_ISO, OpenVMS-E9.2-3: (1 of 1) , mounted on  _REMY1$DKA0:

Navigate to the CDROM mount folder:

SET DEF REMY1$DKA0:[000000]

Check the files in there. My output has the source ZIP, but in earlier attempts the other files were there as well:

DIR

Output:

Directory REMY1$DKA0:[000000]

TETRIS312.ZIP;1     TRANS.TBL;1

Total of 2 files.

Copy files

The CD-ROM ISO is read only, so extracting the ZIP files will not work. Copy over the source file to your login folder:

copy TETRIS312.ZIP;1 SYS$LOGIN

Repeat the process for the product installers, copy those as well. Feel free to create a different folder to put the files in.

Install C compiler and curl on OpenVMS

This step is optional if you are using the pre-built hobbyist virtual machine. My installation did not have the compilers installed so I had to do that. The curl installer can be downloaded here.

Change directory to SYS$LOGIN (or the folder you copied the files from the ISO):

SET DEF SYS$LOGIN

Execute the following command to install the C compiler (and in my case, curl):

product install

Output:

_Product name (* to show list): *

Enter * to list all installers in this folder. Output:

   1 - VSI X86VMS C X7.6-4                 Layered Product
   2 - VSI X86VMS CURL V8.0-1A             Layered Product
   3 - All products listed above
   ? - Help
   E - Exit

Choose one or more items from the menu: 3

Enter the number that matches All products listed above. In my case 3. Installation takes a few minutes, output:

Performing product kit validation of signed kits ...
%PCSI-I-VSIVALPASSED, validation of REMY1$DKA100:[SYS0.][SYSMGR]VSI-X86VMS-C-X07
06-004-1.PCSI$COMPRESSED;1 succeeded
%PCSI-I-VSIVALPASSED, validation of REMY1$DKA100:[SYS0.][SYSMGR]VSI-X86VMS-CURL-
V0800-1A-1.PCSI$COMPRESSED;1 succeeded

The following products have been selected:
  VSI X86VMS C X7.6-4                    Layered Product
  VSI X86VMS CURL V8.0-1A                Layered Product

Do you want to continue? [YES]


Configuration phase starting ...

You will be asked to choose options, if any, for each selected product and for
any products that may be installed to satisfy software dependency requirements.

Configuring VSI X86VMS C X7.6-4: VSI C for OpenVMS

  Copyright 2023 VMS Software, Inc.

  This software is sold by VMS Software, Inc.

  PAKs used: C or C-USER

* This product does not have any configuration options.

  Copyright 2023 VMS Software, Inc.

   VMS SOFTWARE, INC. CONFIDENTIAL. This software is confidential
   proprietary software licensed by VMS Software, Inc., and is not
   authorized to be used, duplicated or disclosed to anyone without
   the prior written permission of VMS Software, Inc.
   Copyright 2023 VMS Software, Inc.

   HPE CONFIDENTIAL. This software is confidential proprietary software
   licensed by Hewlett Packard Enterprise Development, LP, and is not
   authorized to be used, duplicated or disclosed to anyone without the
   prior written permission of HPE.
   Copyright 2023 Hewlett Packard Enterprise Development, LP


Configuring VSI X86VMS CURL V8.0-1A

  VMS Software Inc.

* This product does not have any configuration options.

Execution phase starting ...

The following products will be installed to destinations:
  VSI X86VMS C X7.6-4                    DISK$X86SYS:[VMS$COMMON.]
  VSI X86VMS CURL V8.0-1A                DISK$X86SYS:[VMS$COMMON.]

  Portion done: 0%...40%....

This takes a few minutes. Output continues after 100%:

  The following products have been installed:
    VSI X86VMS C X7.6-4                    Layered Product
    VSI X86VMS CURL V8.0-1A                Layered Product

  %PCSI-I-IVPEXECUTE, executing test procedure for VSI X86VMS C X7.6-4 ...
  %PCSI-I-IVPSUCCESS, test procedure completed successfully

  VSI X86VMS C X7.6-4: VSI C for OpenVMS

    The release notes are located in the file SYS$HELP:CC.RELEASE_NOTES.

    A startup file SYS$STARTUP:DECC$STARTUP.COM has been provided.

      It contains commands which can be executed after the product install
      procedure has been run and at startup to allow for the best compilation
      performance.  You may want to invoke this command file from your
      system's site-specific start up file.  This command file does not
      have to be invoked for correct operation of VSI C.

  VSI X86VMS CURL V8.0-1A

    Post-installation tasks are required.


    To start cURL at system boot time, add the following lines to
    SYS$MANAGER:SYSTARTUP_VMS.COM:

      $ file := SYS$STARTUP:CURL$STARTUP.COM
      $ if f$search("''file'") .nes. "" then @'file'

    To stop cURL at system shutdown, add the following lines to
    SYS$MANAGER:SYSHUTDWN.COM:

      $ file := SYS$STARTUP:CURL$SHUTDOWN.COM
      $ if f$search("''file'") .nes. "" then @'file'

Configure curl on OpenVMS

As indicated by the output of the installer, curl requires some configuration before it can be used. We have to add some commands to the startup sequence. First make sure the editor knows about your terminal:

SET TERM/INQUIRE

If you don't execute that command, EDIT will error and not work:

%TPU-E-NONANSICRT, SYS$INPUT must be supported CRT

To read more on editting via SSH, check out my other article. That article shows you how to edit some other files to make that INQUIRE command no longer needed.

Edit the following file:

EDIT SYS$MANAGER:SYSTARTUP_VMS.COM

Near the bottom, before the exit lines, add the following:

$ file := SYS$STARTUP:CURL$STARTUP.COM
$ if f$search("''file'") .nes. "" then @'file'

Save and exit with CTRL+Z. For convenience, execute these lines in your current terminal as well by pasting them.

To use curl, we must define it as a "foreign command", just as we did for zip/unzip:

CURL :== $CURL$ROOT:[BIN]CURL.EXE

You can add the CURL :==... line at the bottom of your SYLOGIN.COM file in the SYS$LOGIN folder to make this permanent.

Test the command to make sure all of the above was done correctly:

curl --version

Output:

curl 8.0.1 (OpenVMS IA64) libcurl/8.0.1 OpenSSL/1.1.1s zlib/1.2.8 libssh2/1.9.0_
DEV nghttp2/1.40.90
Release-Date: May  7 2023
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mq
tt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc HSTS HTTP2 HTTPS-proxy IPv6 libz NTLM SSL TLS-SRP UnixSockets

Funny how it still says OpenVMS IA64. I suspect that is a remnant of the cross compilation via Itaniums that VSI did to bootstrap OpenVMS on x86.

If you haven't transferred the source code via an ISO, download it with Curl:

curl -O tetris-312.zip http://raymii.org/s/inc/downloads/tetris-312.zip

Unzip the source code

With everything installed and configured we can start with the actual fun of trying to compile TETRIS.

Make sure you have defined a "foreign command", for unzip:

unzip :== $SYS$COMMON:[SYSHLP.UNSUPPORTED.UNZIP]UNZIP.EXE

Start by unzipping the source archive:

unzip tetris312.zip;1

Output:

Archive:  SYS$SYSROOT:[SYSMGR]TETRIS312.ZIP;1
  inflating: [.tetris_3_1_2]axpobjs.zip
   creating: [.tetris_3_1_2.bm-3d]
  inflating: [.tetris_3_1_2.bm-3d]rot00.xbm
  [...]

Change directory to the unzipped folder:

set def [.tetris_3_1_2]

Check the files:

 DIR

Output:

Directory SYS$SYSROOT:[SYSMGR.tetris_3_1_2]

axpobjs.zip;1       bm-3d.DIR;1         bm-plain.DIR;1      compile.com;1
compile_axp.com;1   compile_decc.com;1  copyright.;1        imakefile.;1
link.com;1          link_axp.com;1      link_decc.com;1     makefile.;1
makefile.std;1      patchlevel.h;1      playing.c;1         pwd.h;1
readme.;1           revisions.;1        tetris.c;1          tetris.exe_axp;1
tetris.exe_vax;1    tetris.h;1          tetris.hlp;1        tetris.man;1
ticon.xbm;1         unix_time.h;1       unix_types.h;1      utils.c;1
vaxobjs.zip;1       vms.opt;1           vms_axp.opt;1       vms_decc.opt;1
x11.DIR;1           xvmsutils.olb;1     xvmsutils.olb_axp;1
xvmsutils.olb_decc;1

Total of 36 files.

Compile Tetris

Without any changes, compilation fails. Try it out:

CC/define=(VMS) tetris.c

This command comes from the included compile.com file. Output:

#endif !_UNIX_TIME_
.......^
%CC-I-IGNOREEXTRA, Spurious token(s) ignored on preprocessor directive line.
at line number 74 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]unix_time.h;1

#define NULL            (void *) 0
.........................^
%CC-W-MACROREDEF, The redefinition of the macro "NULL" conflicts with a current definition because the replacement lists differ.  The redefinition is now in effect.
at line number 67 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]unix_types.h;1

#endif _FD_MASK_
.......^
%CC-I-IGNOREEXTRA, Spurious token(s) ignored on preprocessor directive line.
at line number 93 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]unix_types.h;1

#define FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
...............^
%CC-W-MACROREDEF, The redefinition of the macro "FD_SET" conflicts with a current definition because the spelling of one or more parameters is different.  The redefinition is now i
n effect.
at line number 106 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]unix_types.h;1

#define FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
...............^
%CC-W-MACROREDEF, The redefinition of the macro "FD_CLR" conflicts with a current definition because the spelling of one or more parameters is different.  The redefinition is now i
n effect.
at line number 107 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]unix_types.h;1

#define FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
.................^
%CC-W-MACROREDEF, The redefinition of the macro "FD_ISSET" conflicts with a current definition because the spelling of one or more parameters is different.  The redefinition is now
 in effect.
at line number 108 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]unix_types.h;1

#define FD_ZERO(p)      bzero((char *)(p), sizeof(*(p)))
................^
%CC-W-MACROREDEF, The redefinition of the macro "FD_ZERO" conflicts with a current definition because the spelling of one or more parameters is different.  The redefinition is now
in effect.
at line number 109 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]unix_types.h;1

#endif  _UNIX_TYPES_
........^
%CC-I-IGNOREEXTRA, Spurious token(s) ignored on preprocessor directive line.
at line number 119 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]unix_types.h;1

typedef long            off_t;
........................^
%CC-E-NOLINKAGE, In this declaration, "off_t" has no linkage and has a prior declaration in this scope at line number 109 in file SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 (text module
STDIO).
at line number 51 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]pwd.h;1

        struct timeval {
........^
%CC-E-REDEFSTRUCT, In this declaration, the struct "timeval" is redefined.
at line number 672 in module TIME of text library SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1

    struct itimerval {
....^
%CC-E-REDEFSTRUCT, In this declaration, the struct "itimerval" is redefined.
at line number 682 in module TIME of text library SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1

typedef int size_t;
............^
%CC-E-NOLINKAGE, In this declaration, "size_t" has no linkage and has a prior declaration in this scope at line number 99 in file SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 (text module
STDIO).
at line number 66 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]unix_types.h;1

typedef struct fd_set {
........^
%CC-E-REDEFSTRUCT, In this declaration, the struct "fd_set" is redefined.
at line number 100 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]unix_types.h;1

    typedef __dev_t dev_t;
....................^
%CC-E-NOLINKAGE, In this declaration, "dev_t" has no linkage and has a prior declaration in this scope at line number 55 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]pwd.h;1.
at line number 46 in module TYPES of text library SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1

    typedef __gid_t gid_t;
....................^
%CC-E-NOLINKAGE, In this declaration, "gid_t" has no linkage and has a prior declaration in this scope at line number 54 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]pwd.h;1.
at line number 54 in module TYPES of text library SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1

    typedef __ino_t ino_t;
....................^
%CC-E-NOLINKAGE, In this declaration, "ino_t" has no linkage and has a prior declaration in this scope at line number 56 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]pwd.h;1.
at line number 62 in module TYPES of text library SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1

    typedef __mode_t mode_t;
.....................^
%CC-E-NOLINKAGE, In this declaration, "mode_t" has no linkage and has a prior declaration in this scope at line number 57 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]pwd.h;1.
at line number 70 in module TYPES of text library SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1

    typedef __nlink_t nlink_t;
......................^
%CC-E-NOLINKAGE, In this declaration, "nlink_t" has no linkage and has a prior declaration in this scope at line number 58 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]pwd.h;1.
at line number 78 in module TYPES of text library SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1

    typedef __pid_t pid_t;
....................^
%CC-E-NOLINKAGE, In this declaration, "pid_t" has no linkage and has a prior declaration in this scope at line number 50 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]pwd.h;1.
at line number 94 in module TYPES of text library SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1

    typedef __ssize_t ssize_t;
......................^
%CC-E-NOLINKAGE, In this declaration, "ssize_t" has no linkage and has a prior declaration in this scope at line number 52 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]pwd.h;1.
at line number 117 in module TYPES of text library SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1

    typedef __uid_t uid_t;
....................^
%CC-E-NOLINKAGE, In this declaration, "uid_t" has no linkage and has a prior declaration in this scope at line number 53 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]pwd.h;1.
at line number 125 in module TYPES of text library SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1

        typedef __key_t  key_t;
.........................^
%CC-E-NOLINKAGE, In this declaration, "key_t" has no linkage and has a prior declaration in this scope at line number 59 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]pwd.h;1.
at line number 181 in module TYPES of text library SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1

    strncpy(myscore.myname, (const) vmsusername,vmsuserlen);
............................^
%CC-W-CVTDIFTYPES, In this statement, "(const )vmsusername" of type "int", is being converted to "pointer to const char".
at line number 193 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]tetris.c;1

        myscore.myname[19] = '\0';
.......................^
%CC-I-SUBSCRBOUNDS, In this statement, an array is being accessed outside the bounds specified for the array type.
at line number 437 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]tetris.c;1

You can see that this is old code due to the following lines:

typedef int size_t;
............^
%CC-E-NOLINKAGE, In this declaration, "size_t" has no linkage and has a prior declaration in this scope at line number 99 in file SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 (text module
STDIO).
at line number 66 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]unix_types.h;1

Fixing the compile errors

If you want to use vim for editing instead, download it from here, extract the ZIP file and define a foreign command:

vim :== $SYS$LOGIN:VIM.EXE

After some investigation, I found a few small fixes. The old code defined a lot of its own types which are now done by the newer compiler by default. We can easily work around that by not including those custom headers. In the tetris.h file comment the following 3 lines:

/* #include        "pwd.h"
#include        "unix_time.h"
#include        "unix_types.h" */

Make sure to use /* ... */ and not // to comment. Reason why will become important later on. Try recompiling now, the errors have greatly reduced:

        strncpy(myscore.myname, (const) vmsusername,vmsuserlen);
    ............................^
    %CC-W-CVTDIFTYPES, In this statement, "(const )vmsusername" of type "int", is being converted to "pointer to const char".
    at line number 193 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]tetris.c;2

            myscore.myname[19] = '\0';
    .......................^
    %CC-I-SUBSCRBOUNDS, In this statement, an array is being accessed outside the bounds specified for the array type.
    at line number 437 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]tetris.c;2

Those pesky conversion and array bounds checks. If we wanted to write memory-safe software we would have used Rust. But who worried about that in 1992 when writing a simple Tetris game?

We have a trick up our sleeve. Try compiling with the old vaxc standard:

    CC /STANDARD=vaxc tetris.c

No output errors now! I first tried /STANDARD=relaxed, but that gave the same errors. If we would have commented with // instead of /*, that would give a compilation error with this old standard:

//include        "pwd.h"
^
%CC-E-DECLARATOR, Invalid declarator.
at line number 35 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]tetris.h;11

Continue on with the next source file, that will compile without errors:

CC /STANDARD=vaxc utils.c

The last file will error out:

CC /STANDARD=vaxc playing.c

Output:

static struct timezone tzone = {0, 0};
...............................^
%CC-E-NOINIT, The type of tzone does not permit initialization.
at line number 46 in file SYS$SYSROOT:[SYSMGR.tetris_3_1_2]playing.c;4

In the file unix_time.h there is the following code:

struct timezone
{
        int     tz_minuteswest; /* minutes west of Greenwich */
        int     tz_dsttime;     /* type of dst correction */
};

However, we commented out that header inclusion in tetris.h. Edit tetris.h again and paste the above struct somewhere on top, below the X11 includes. Try compilation again, this time, no errors!

We're almost finished. You should have 3 .OBJ files now.

Linking tetris on OpenVMS x86

Now that we have .OBJ files we must link them. However, that will fail as well:

LINK tetris,utils,playing

Output:

%ILINK-W-COMPWARN, compilation warnings
        module: TETRIS
        file: SYS$SYSROOT:[SYSMGR.tetris_3_1_2]tetris.OBJ;8
%ILINK-W-NUDFSYMS, 44 undefined symbols:
%ILINK-I-UDFSYM,        XALLOCCOLOR
%ILINK-I-UDFSYM,        XBELL[...]
%ILINK-I-UDFSYM,        XVISUALIDFROMVISUAL
%ILINK-W-USEUNDEF, undefined symbol XRMGETFILEDATABASE referenced
        section: $CODE$
        offset: %X0000000000000188
        module: TETRIS
        file: SYS$SYSROOT:[SYSMGR.tetris_3_1_2]tetris.OBJ;8
%ILINK-W-USEUNDEF, undefined symbol XRMMERGEDATABASES referenced
        section: $CODE$
        offset: %X000000000000019B
        module: TETRIS
        file: SYS$SYSROOT:[SYSMGR.tetris_3_1_2]tetris.OBJ;8
%ILINK-W-USEUNDEF, undefined symbol XRESOURCEMANAGERSTRING referenced
        section: $CODE$
        offset: %X00000000000001AE
        module: TETRIS
        file: SYS$SYSROOT:[SYSMGR.tetris_3_1_2]tetris.OBJ;8

Just as on Linux (-lX11 -lXaw), we must tell the linker where it can find the X11 includes. Create the following file:

EDIT x86.opt

Paste in the following:

SYS$SHARE:DECW$XTSHR/SHARE
SYS$SHARE:DECW$XLIBSHR/SHARE

Save with CTRL+Z. Link again, with this file included:

  link tetris,utils,playing,x86.opt/opt

You might receive a warning:

%ILINK-W-COMPWARN, compilation warnings
    module: TETRIS
    file: SYS$SYSROOT:[SYSMGR.tetris_3_1_2]tetris.OBJ;8

Retry compiling all files and link again. No more errors then!

Playing Tetris on x86 OpenVMS

After all the hard work, you should now have an TETRIS.EXE file:

dir *.exe

Output:

Directory SYS$SYSROOT:[SYSMGR.tetris_3_1_2]

tetris.EXE;7        tetris.EXE;6        tetris.EXE;5        tetris.EXE;4
tetris.EXE;3        tetris.EXE;2        tetris.EXE;1

Total of 7 files.

I have multiple due to playing around with the code and compiling.

To run tetris, the easiest way is to use the CDE desktop. Open the file manager, navigate to the Tetris folder and double click the EXE file.

If you don't want to run CDE, you can also use bare X11 to run just tetris. Make sure you have an X11 server set up. Execute the following command:

SET DISPLAY/CREATE/NODE=<IP of your X11 host>/TRANSPORT=TCPIP/EXEC

Then run TETRIS:

RUN TETRIS.EXE

Output:

GENERIC TETRIS V3.1.2
Copyright (C) 1992-93      Q. Alex Zhao, azhao@cc.gatech.edu
     GENERIC TETRIS comes with ABSOLUTELY NO WARRANTY.

The X11 window should now contain just Tetris, no window borders or anything:

tetris x11

Have fun beating your highscore!

Tags: alpha , blog , cde , dec , decwindows , games , itanium , openvms , pdp , rust , tetris , vax , virtualbox , vms , vsi , x86