Skip to content

Coding games for ELKS

toncho11 edited this page Sep 28, 2024 · 28 revisions

There is currently an optimized port of Doom 1 that runs on 8088. Doom uses direct VGA programming as explained below. Playing the game requires some configuration explained here. A bootable downloadable image ELKS + DOOM can be found here.

Supported Graphics modes

  • VGA
  • CGA (potentially Tandy's TGA as well)
  • PC98

For the CGA you need to also recompile the x-nano apps with the CGA driver enabled (instead of the default VGA). This is done by unsetting the CONFIG_HW_VGA in your .config. CGA mode means that the IBM 5153 monitor should be supported when used with suitable CGA card.

Supported compilers

  • gcc16 - only small and (experimental) medium model
  • Open Watcom - all memory models (compiles Doom)

Several text (ASCII art) based games are available for ELKS

There are 3 ways you can program graphical games on ELKS

1. Using x-nano

There are several VGA demos based on X-nano shipped with ELKS. There are at least two games available:

  • nxtetris
  • landmine

More code samples are available in: /elkscmd/nano-X/demos

If the nxlandmine is compiled with the CGA driver, export MONOMODE to set the environment variable is needed.
For nxtetris, unsetting this variable gets better graphic.

2. Using direct access to the VGA memory

This is used by Doom. The following code switches to VGA mode 0x13, draws two lines, waits 3 seconds and then it switches back to text mode. It can be compiled with ../cross/bin/ia16-elf-gcc ./vgatest.c -o vgatest -melks-libc -mcmodel=small. Start it with ./vgatest. It uses the ia16-elf-gcc compiler used to compile the entire ELKS project.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define VGA_256_COLOR_MODE  0x13      /* use to set 256-color mode. */
#define TEXT_MODE           0x03      /* use to set 80x25 text mode. */

#define SCREEN_WIDTH        320       /* width in pixels of mode 0x13 */
#define SCREEN_HEIGHT       200       /* height in pixels of mode 0x13 */
#define NUM_COLORS          256       /* number of colors in mode 0x13 */

#define sgn(x) ((x<0)?-1:((x>0)?1:0)) /* macro to return the sign of a
                                         number */
typedef unsigned char  byte;
typedef unsigned short word;

byte __far *VGA=(byte __far *)0xA0000000L;        /* this points to video VGA memory. */

/**************************************************************************
 *  set_mode                                                              *
 *     Sets the video mode.                                               *
 **************************************************************************/

void set_mode(byte mode)
{
   // SI, DI, BP, ES and probably DS are to be saved
   // cli and sti are used to make a proper BIOS call from ELKS
   __asm__(
  "push %%si;"
  "push %%di;"
  "push %%bp;"
  "push %%es;"
  "cli;"
  "mov %%ah,0;" 
  "mov %%al,%0;" 
  "int $0x10;"
  "sti;"
  "pop %%es;"
  "pop %%bp;"
  "pop %%di;"
  "pop %%si;"
     : /* no outputs */
     : "r" (mode)
     : ); //list of modified registers
}

/**************************************************************************
 *  plot_pixel                                                            *
 *    Plot a pixel by directly writing to video memory, with no           *
 *    multiplication.                                                     *
 **************************************************************************/

void plot_pixel(int x,int y,byte color)
{
  /*  y*320 = y*256 + y*64 = y*2^8 + y*2^6   */
  VGA[(y<<8)+(y<<6)+x]=color;
}

int main()
{
  set_mode(VGA_256_COLOR_MODE);       /* set the video mode to 256 colors 320 x 200 */
								 
  for (int i=0;i<60;i++)
  	plot_pixel(100+i,100,5);

  for (int i=0;i<60;i++)
        plot_pixel(100,100+i,0xA);

  sleep(3);
  
  set_mode(TEXT_MODE);                /* set the video mode back to text mode. */

  return 0;
}

You can adapt code from David Brackeen's VGA tutorial and draw whatever you need on the screen.

3. Using Basic

Currently graphics routines are available on the IBM PC in CGA mode and the PC-98 platform. Here are some sample codes to draw lines in the CGA mode.

  • MODE 1 gets to the graphic mode and MODE 0 gets back to the text mode.
  • COLOR can set the foreground color (0-3) in the first parameter.
  • the second parameter is reserved for the background color, but currently it is not supported.
10 MODE 1
20 COLOR 1,0
30 PLOT 100,50
40 DRAW 200,50
50 DRAW 200,100
60 DRAW 100,100
70 DRAW 100,50
80 COLOR 2,0
90 PLOT 150,150
100 DRAW 100,100
110 PLOT 150,150
120 DRAW 200,100
130 INPUT A$
140 MODE 0

Reference for other basic command can be found in Basic's README. You can also have a look at snakecga.bas port.

Discussion

More on programming games for ELKS is here: https://github.com/ghaerr/elks/issues/871