Creating Video Games
Some
background:
There are lots of video games out there written for
16 bit, and with a little work, it is still possible to create one. Unfortunately, the documentation is harder to
come by. I no longer have my texts
detailing the various graphics modes and how they work. But I have lots of examples and found some
additional resources online. You may have to do some leg-work to make your graphics happen. You can search links for programming various
video cards, which are listed below.
Video
card standards
CGA (Color Graphics Adapter) was the first standard that could
be used for graphics. It was introduced by IBM in 1981, but such cards were
very expensive and 320x200 with 4 colors or 640x200 with 2 colors was
incommensurate to professional use. After EGA cards were introduced, the CGA
cards became affordable and were considered as cheap solution.
HGC (Hercules Graphics Card) was a monochrome graphics
controller developed by Hercules Computer Technology, Inc. in 1982. It supported
a high-resolution text mode with a clearer text display than the CGA standard
ever could offer, and a single graphics mode in 720x348. The Hercules cards
were widely supported and usually connected to a monochrome monitor with a
green, yellow or white display.
EGA (Enhanced Graphics Adapter) was developed by IBM as a
successor to CGA in 1984. Such cards were able to display 16 colors at
resolutions up to 640x350, but you needed a special EGA monitor to do this.
VGA (Video Graphics Array) is a video card standard introduced
in 1987. It is still supported today (December 2008). It's
advantage was that you was able to use a wide range of display modes, even
though they were limited to 400 lines at 70 Hz or 480 lines at 60 Hz. The most
common modes were 320x200 at 256 colors and 640x480 at 16 colors.
VBE (VESA BIOS Extension) originally was an enhancement to VGA
and supported more powerful video modes. In 1989, it was first specified as
SVGA (Super Video Graphics Array) by the Video Electronics Standards Association
(VESA) and later enhanced up to a resolution of 1600x1200. As not all video
cards supported such functionalities, there were additional programs like UniVBE (later Scitech Display
Doctor) to provide them by software.
As IBM had a quasi-monopoly in PC
hardware in the 80s, the video drivers for CGA, EGA and VGA have been directly
integrated into the BIOS. That was not unimportant, because DOS didn't have a
graphical subsystem like GDI, DirectX or the X Window system. Since every software had to use own drivers to use hardware,
developers mostly restricted themself to VGA. After 1990, IBM lost his market
power. So even today, the VGA driver is the best one, if you didn't have
installed the right video driver, yet.
http://www.wagemakers.be/english/doc/vga From this link:
1. Change to a VGA resolution.
With
BIOS interrupt 13 AH = 00 we're able to change the current screen resolution
(See below).
Example:
Change to medium resolution:
To go into graphics mode 13h and plot a pixel
1.
Mov ax,13h;MCGA
320x200 256 color graphics mode
2. Int
10h
3. mov ax, row
4. mov bx, column
5. mov cx,320
6. mul cx
7. add ax,bx
8. xchg si,ax
9. mov bx, 0a000h;location of video mem for this
mode
10. mov es, bx; … note es must be
pointing at video mem:
11.
mov word [es:si], 9 ; display bright-blue pixel
Al (hex) |
video mode |
|
|
In
the next paragraphs we'll discuss meanly the standard VGA resolution (12h)
These days most VGA-boards has "Super VGA" resolutions, in the next
table you'll find the information to change to a "VESA Super VGA"
INT 10h |
AX = 4F02h |
BX = mode |
BX |
video mode |
|
|
When
your VGA BIOS support this function AH will become 00h, otherwise AH will
return 01h. The issues in the next paragraph can also be use
in the VESA resolution 800 x 600 16 colors.
The
standard IBM VGA card has 16 color therefore every pixel needs 4 bits (2^4 =
16) The VGA graphical card uses bitplanes, every main color has his own memory area in the video
memory. Because the memory address is equal for every main color (A000:0000h
memory mapped) we have to program the sequencer to select the right memory
bank.
register
selection with port 03C4h.
register |
name |
|
|
With
the Map Mask register we can select to which color plane we write. (translation: blue, green, red, intensity)
When
we set bit 0 we'll write to the blue bitplane, if we
set bit 0 and 1 (3) we'll write to the to
blue bitplane. The next example will elucidate the
above theory.
.MODEL SMALL
.CODE
start:
mov
ax,012h ;VGA
mode
int
10h ;640 x 480 16 colors.
mov ax,0A000h
mov
es,ax ;ES
points to the video memory.
mov dx,03C4h
;dx = indexregister
mov
ax,0F02h ;INDEX = MASK MAP,
out dx,ax ;write all the bitplanes.
mov di,0
;DI pointer in the video memory.
mov cx,38400
;(640 * 480)/8 = 38400
mov
ax,0FFh ;write to every pixel.
rep
stosb
;fill the screen
mov
ah,4ch ;go back
int
21h ; to DOS.
END start
With
mov ax,0F02h, out dx,ax we select all the bitplanes
this results in the color white. If we change mov ax,0F02h to mov ax,0102h we'll get a
blue screen ;-).
Another
advantange of VGA is the ability to modify the
colors, so it's possible to give pictures a more "real" look.
There're two way the modify the video palette program
direct to the video hardware or use the video software interrupt (INT 10h).
Below you'll find howto change the palette by INT
10h.
With INT 10h AX = 1010h we can change the palette of one color, BX contains the
color register, CH the green value, CL the blue value and DH the red value.
There is a difference between "color register" and "color number"
we can solve this by first request the "color register" of the
"color number". We can do this with INT 10 AX = 1007h, BL contains
the color number the color register will be returned in BH. The next example
will proof that practice is less complicated that the theory.
;------------------------------------------
;Modify the palette of one color.
;BX = color number
;ch = green
;cl = blue
;dh = red
;------------------------------------------
pal
PROC
push ax
mov
bh,0
mov
ax,1007h
int
10h
mov
bl,bh
mov
bh,0
mov
ax,1010h
int
10h
pop ax
ret
pal
ENDP
Reading
the Video memory is more or less the same as writing to it. We have to change
the graphical control to read mode. This is possible with port address 03CEh
and 03CFh.
The next table gives you a
overview of the possible functions.
Mode adjustment by port 03CEh.
register |
Name |
|
|
When
we set port 03CEh to 3 we set the VGA card in read mode with port 03CFh we can
specify the color bitplane to read. In the next table
contains the colors with equivalent values.
bitplane selection by port 03CFh
3 |
blue |
The
next procedure will demonstrate the above theory. It read one byte in the 4
color bitplanes (BGRI), with
SI we specify the byte address.
PUBLIC readbyte
;--------------------------------------------
;Read one byte in the video memory
;call : SI byte address
;answer : al,ah,bl,bh
-> bl,gr,rood,inten
;--------------------------------------------
readbyte
PROC NEAR
push cx
push dx
push si
push es
mov
ax,0A000h
mov
es,ax
mov
dx,03ceh
mov
ax,0005h
out dx,ax
mov
ax,0304h ;AH = bitplane, AL = read modus
rb01: out dx,ax ;go to read mode
mov
bh,es:[si] ;read
the blue byte
dec
ah
out dx,ax ;AH = green
mov
bl,es:[si] ;read the green byte
dec
ah
out dx,ax ;AH = red
mov
ch,es:[si] ;read
the red byte
dec
ah
out dx,ax ;AH = intensity
mov
cl,es:[si] ;read the intensity byte
mov ax,cx
pop es
pop si
pop dx
pop cx
ret
readbyte
ENDP
There're
4 different write modes; replace, AND, OR and XOR, we change the write mode by
the "Data Rotate/Function Select" register (see table in paragraph
2).By putting 3 in the selection register 03CEh we select the "Data
Rotate/Function Select".
Like the name suggest we also have the ability the rotate the date, this isn't
often used since it's faster to rotate the date with the normal processor.
With the dataregister at port address 03CFh we can
specify how to the data is written to the screen.
write mode selection by port
03CFh
bit 4 bit3 |
function |
|
|
sample:
mov ax,1803h
mov dx,03CEh
out dx,ax
Will
set the VGA card write mode to XOR.
Drawing
a line in assembly isn't that easy... and it is very important not to use to
complicated functions (cos, sin ...) since this is
too difficult to program and (more important) will slow the function.
The most widely used function to draw a line is the so called Bresenham algoritme which is
published in IBM System Journal in 1965.
The
equation of a line : y = (dy/dx).x
When
the line is closer to point A, we have to draw point A. When the line is closer
to point B we need to draw point B.
a = (yi+1) - (dy/dx).xi
b = (dy/dx).xi - yi
(b-a) = 2.(dy/dx).xi - 2.yi - 1
(b-a).dx = 2.(dy.xi - yi.dx)
- dx
suppose di = (b-a).dx
di = 2.(dy.xi - yi.dx) - dx
We
need to calculate di with the information of the last drawn point:
(di - di-1) = 2.(dy.xi - yi.dx) - dx - 2.(dy.xi-1 - yi-1.dx) + dx
(di - di-1) = 2.(dy.(xi - xi-1) - dx(yi - yi-1))
For
the step in the x direction (xi - xi-1) we choose 1.
(di - di-1) = 2.(dy - dx(yi - yi-1))
The
value of (yi - yi-1) depends on where we have to draw
the point, (yi - yi-1) is 1 when we need to draw
point A (yi-1 +1) and will be 0 if we need to draw point B (yi
= yi-1).
When
we have to draw point A : (di - di-1) = 2.(dy - dx)
When we have to draw point B : (di - di-1) = 2.dy
http://wiki.osdev.org/Drawing_In_Protected_Mode
Excerpted from link above:
The
cleanest way to set up your video mode is to go through the video BIOS. It can
be performed through the regular Int 0x10 interface, or through the (optional) Protected mode interface offered by VBE3. As you can
guess, Int 0x10 requires a 16-bit environment, so you can
only use it in Real Mode
or Virtual 8086
Mode
Practically, the options
are (in order of difficulty):
You set up the mode you
want at early stage (in the bootloader) before
entering protected mode.
You let GRUB do the switch for
you. (Currently only works with patched GRUB, or GRUB 2. You may
download the patches directly from here.)
You switch back to Real Mode
or Unreal Mode
for setting the proper video mode
You write a VGA driver
that can do low-resolution modes on practically all hardware
You use the PMID from VBE3,
if present
You set up a V8086
monitor
that will execute the mode-switching code
You run some software code translation tool to produce pmode code out of bios rmode code. (SANiK
You
write a driver for your specific graphics card
how many bytes of VRAM you should skip to go one pixel
right. |
Pitch
and pixel width are usually announced by VESA mode info.
Alien code Here
is snake, a thingy that creeps along and turns a corner. Similarly,
this ball “bounces” up and down. (To
make pong, ball needs to move horizontally & vertically at the same time.) This
program prints letters/colors This
program draws coordinate axes. It might
be the basis for a simple graphing program. Here
is boatgame… Boat and sub move back and forth at different speeds. Note torpedo has been fired. This
uses high res graphics to draw a rectangle… does not properly terminate in
dosbox.