Coding games for ELKS - ghaerr/elks GitHub Wiki
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.
- VGA
- CGA (potentially Tandy's TGA as well)
- PC98 (Japanese PC-98 computers)
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.
- ia16-gcc - only small and (experimental) medium model
- Open Watcom - all memory models (compiles Doom)
- ELKSmoria port of Moria 1983
- ELKSAdvent port of Advent
- ttytetris
- ttypong
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 enabled (VGA disabled), you need to execute export MONOMODE
(sets the MONOMODE environment variable). For nxtetris, unsetting this variable gets better graphics.
This method 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.
Currently two platforms are supported:
- CGA / IBM PC
- PC98 (Japanese PC-98 computers)
As VGA supports CGA graphics, you will be able to draw on a VGA monitor on an IBM PC. Here are some sample codes to draw lines in 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 commands can be found in Basic's README. You can also have a look at snakecga.bas port.
More on programming games for ELKS is here: https://github.com/ghaerr/elks/issues/871