This is a text-only version of the following page on https://raymii.org:
---
Title : Compiling TETRIS from 1992 on OpenVMS x86 in 2024!
Author : Remy van Elst
Date : 18-08-2024 14:33
URL : https://raymii.org/s/blog/Tetris_from_1992_on_OpenVMS_x86_in_2024.html
Format : Markdown/HTML
---
Since [DECWindows / CDE](/s/blog/OpenVMS_x86_E9.2-3_fixes_CDE_and_adds_Guest_Console.html) 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](/s/blog/OpenVMS_CDE_Desktop_remote_x_axpbox.html) and also an article on how to run [CDE on modern linux, since it's still developed](/s/blog/The_Common_Desktop_Environment_CDE_is_still_developed_in_2021.html#toc_6). Both articles included a game, **GENERIC-TETRIS** from 1992, [written by Qiang Alex Zhao](https://web.archive.org/web/20240815073318/https://sites.cc.gatech.edu/gvu/people/qiang.a.zhao/Games.html).
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](/s/tags/openvms.html).
![tetris on x86 openvms](/s/inc/img/8443ae6737384b76938c6b0597d1c08f.png)
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](https://vmssoftware.com/products/licenses/) or wait
until the [Hobbyist License Virtual Machine]
(https://vmssoftware.com/community/community-license/) 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](/s/inc/downloads/tetris_openvms_x86.exe).
Make sure to [have the desktop up and running](/s/blog/OpenVMS_x86_E9.2-3_fixes_CDE_and_adds_Guest_Console.html).
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](https://raymii.org/s/inc/downloads/tetris-312.zip).
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](/s/inc/img/4897586cb5974a3086ce13359d95f22a.png)
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](/s/blog/OpenVMS_Mount_ISO_and_execute_scripts.html).
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](https://vmssoftware.com/products/curl/).
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](/s/blog/OpenVMS_9.2_for_x86_Getting_Started_part_3.html#toc_0). 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](/s/blog/OpenVMS_9.2_for_x86_Getting_Started_part_3.html#toc_1):
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](/s/blog/OpenVMS_9.2_for_x86_Getting_Started_part_3.html#toc_1):
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]
(https://www.polarhome.com/vim/), 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](https://web.archive.org/web/20230701173548/https://enet4.github.io/rust-tropes/rust-evangelism-strike-force/)
[would have used](https://web.archive.org/web/20220815110335/https://kasma1990.gitlab.io/2017/06/25/nobody-expects-the-rust-evangelism-strike-force/)
[Rust](https://web.archive.org/web/20230701173833/http://n-gate.com/hackernews/2017/02/21/0/).
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]
(/s/blog/OpenVMS_x86_E9.2-3_fixes_CDE_and_adds_Guest_Console.html). 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=/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](/s/inc/img/cd325e17d8bd4218bf8c70cfda467168.png)
Have fun beating your highscore!
---
License:
All the text on this website is free as in freedom unless stated otherwise.
This means you can use it in any way you want, you can copy it, change it
the way you like and republish it, as long as you release the (modified)
content under the same license to give others the same freedoms you've got
and place my name and a link to this site with the article as source.
This site uses Google Analytics for statistics and Google Adwords for
advertisements. You are tracked and Google knows everything about you.
Use an adblocker like ublock-origin if you don't want it.
All the code on this website is licensed under the GNU GPL v3 license
unless already licensed under a license which does not allows this form
of licensing or if another license is stated on that page / in that software:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Just to be clear, the information on this website is for meant for educational
purposes and you use it at your own risk. I do not take responsibility if you
screw something up. Use common sense, do not 'rm -rf /' as root for example.
If you have any questions then do not hesitate to contact me.
See https://raymii.org/s/static/About.html for details.