Skip to content

Coding games for ELKS

toncho11 edited this page Sep 28, 2024 · 26 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.

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

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.

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

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. CGA mode means that the IBM 5153 monitor should be supported.

Discussion

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