Programming
Concepts
Using Chars
Using Maps
Using Worlds
Example
Cursor
|
|
The Virtual Boy is a console
that presents a different kind of display programming. First, programming isn't just have
an image and blitting it at a certain coordinate, implies knowledge of the depth for this
image in a 3D World. Second, many structures in this console are references to a
semi-static section, for optimizing the display process. But, before continue with
programming aspects, let's know some fundamental terms.Concepts
Byte: The 8bit size forever :)
Hword: The 16bit size (2 bytes).
Word: The 32bit size (4 bytes).
Char: The primary structure in image
construction. A fixed tile with 8x8 pixel dimension. Uses a uncompressed format of 2 bits
per pixel. The char memory space can handle 2048 chars.
Background Map: A secondary
structure. Every map represents an image composed of 64x64 chars. To store a BGMap the VB
uses a predefined struct that allows a direct reference with the needed chars for this
map. This structure handles a 2-bit palette. The console can handle 14 different Maps
simultaneously.
Object: Another secondary structure.
An object is used to handle complex animations in a game. Composed of a variable size of
chars. Storing also needs a predefined struct with information about the char used and
it's position and depth in the object. Uses an special 2-bit palette defined for objects.
The console can handle 4 objects simultaneously.
World: A complex structure.
Represents a logical plane of a map or object. This structure is the base of all the
displaying stuff in the VB. Described in a predefined struct that stores position, depth,
special FX for blitting, and other params. The console handles 32 planes or worlds.
After reviewing this concepts, I'll continue with the basic stuff
on display programming. We need an objective, so... imagine you need to display a
stereoscopic box.
Using Chars
As explained above, the char is fundamental to create a image. If
we need to display a box, the first thing we need to do is create a compatible 2
bit-per-pixel(bpp) bitmap for that box. The question is... What can i do that? and... the
answer is... see below :)
Calculate the size: If a char is
composed of 8x8 pixels and we are currently using a 2bpp format the required bits of a
single char are 128 bits. Now, if storing is in bytes (8 bits), the required bytes are 16,
or 8 hwords, or 4 words.
Define the on/off bits: Depending on
the char, you need to define the 1 values and 0 values. For example, the top-left corner
of our box will be:
Rows |
HWord (8pxs) |
Hex Value |
1 |
0000000000000000b |
0000h |
2 |
0000000000000000b |
0000h |
3 |
0000111111111111b |
0FFFh |
4 |
0000111111111111b |
0FFFh |
5 |
0000111111111111b |
0FFFh |
6 |
0000111111111111b |
0FFFh |
7 |
0000111111111111b |
0FFFh |
8 |
0000111111111111b |
0FFFh |
After defining your single char data, we need to
store it in the char memory. The char memory is composed of 4 segments and is mirrored 4
times? yes, 4. The primary segments are:
Starts |
Ends |
Chars Stored |
00006000h |
00007FFFh |
0 - 511 |
0000E000h |
0000FFFFh |
512 - 1023 |
00016000h |
00017FFFh |
1024 - 1535 |
0001E000h |
0001FFFFh |
1536 - 2047 |
To store our box corner in the CHAR0, we can do in
assembler the following (suposse that $1 = 6000h, $2 = 0FFFh):
st.h $0,
0[$1] ;Row 1
st.h $0, 2[$1] ;Row 2
st.h $2, 4[$1] ;Row 3
st.h $2, 6[$1] ;Row 4
st.h $2, 8[$1] ;Row 5
st.h $2, 10[$1] ;Row 6
st.h $2, 12[$1] ;Row 7
st.h $2, 14[$1] ;Row 8
After you store every needed char to display a box, you'll have a
tile based box like this.

Using Maps
We defined the corners in a box. The next step is to construct a
box image. To do this, let's check the definition of the BGMap struct.
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Palett |
Hflip |
Vflip |
0 |
BChar |
Assuming a standard palett "0" (the
palett will be explained in a future reference), and there are no flips (also 0). The only
field we missing is BChar and it'll have the value according of the char we need to
display. The BGMap is composed of 64x64 chars. We need 64x64 structs like this. If a
struct uses 2 bytes (1 hword) then we need 8192 bytes to represent a BGMap.
As defined, the VB uses 14 BGMaps, and the BGMaps are mapped in
the following memory segment:
00020000h - 0003C000h - 14 BGMaps
Storing our box in BGMAP0 can be done using the folowing asm code
(assuming $1 = 20000h and $2 = 0h):
st.h $2,
0[$1] ;Char 1
add 1, $2
;$2 = 1h
st.h $2, 2[$1] ;Char 2
add 1, $2
;$2 = 2h
st.h $2, 128[$1] ;Char 3
add 1, $2
;$2 = 3h
st.h $2, 130[$1] ;Char 4
With this, we have a box image in the BGMAP0, the only missing
thing is displaying this map on the VB LEDs.

Using Worlds
The last thing we need to do is create the needed information to
display our box in a 3D format. Before starting, we need to know the World predefined
struct, that looks like this.
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
LON |
RON |
BGM |
SCX |
SCY |
OVR |
END |
0 |
0 |
MapRef |
Gx |
Gp |
Gy |
Mx |
Mp |
My |
Width |
Height |
Param Base |
0 |
0 |
0 |
0 |
Overplane Character |
0 |
0 |
0 |
0 |
0 |
As you can suppose, the most important fields are
LON, RON & END because if you don't place this fields right, you will never see an
image.
The World memory is mapped in memory as follows:
0003D800h - 0003DBFFh - 32 Worlds (1024
bytes).
The first displayed plane is 31 that is addressed in 0003DBE0h,
and so on to finish in plane 0. If a plane has the END bit set, this world and the rest
are skipped for display (usually for optimization).
There are 4 types of plane, usually defined with the BGM field:
BGM-Value |
Type |
Description |
0 |
Normal |
Blits the MapRef image using as source rect Mx, My and W,
H, and as destination rect Gx, Gy, W, H. The paralax fields will be explained bellow. |
1 |
H-Bias |
Used for displacement effects in rows, using in the
param-base an offset to a hbias table of factors. This method is not quite defined. |
2 |
Affin |
Used for rotation and scale effects. This method is also
no quite defined, maybe I'll write a future reference with this potentially topics. |
3 |
Object |
This is an appart topic that i'll discuss in a future
reference about "Using Objects". |
There are 2 ways to handle the 3D display
operation, one is easy and the other one is not used, but we'll also review that.
Paralax Display: This method is the
most common way to generate a stereoscopic display in VB. As shown above, the World struct
has a field called paralax that means a little displacement in pixel order. The problem of
this method is that the displacement is horizontal, if we need a vertical displacement
this param cannot be helpful (after all, the stereoscopic concept is just horizontal).
Bi-plane displacement: If you need to
make an Horizontal and Vertical displacement, this method is the only way to do that.
Consists in use 2 world planes, one with the LON bit set and the other with the RON bit
set. The LON plane will handle the left eye displacement and the RON plane will handle the
right one. This concept is just if you need a special effect like that, but I think any
game use this method.
For this example, we will use the paralax method, with a 5 pixel
displacement, using the previous defined box map. The only fields we need to fill (in
plane 31) are LON, RON, MapRef, Gx, Gy, Gp, W and H. The plane 30 will have the END field
set (to skip this and the following planes).
At least, to display this box, just write the following lines in
asm (assuming $1 = 3DE00h and $5 as our variable value):
xor $5, $5
;Var
= 0
movea 0x0C00, $5, $5 ;Setting a 0xC000 means
shl 4, $5
;only LOn, ROn set & Map = 0
st.h $5, 0[$1] ;Store value
xor $5, $5
;Var
= 0
movea 0x0060, $5, $5 ;GX = 0x60 (Screen)
st.h $5, 2[$1]
mov 5, $5
;GP = 5
st.h $5, 4[$1] ;A Simple 3D
Effect
xor $5, $5
;Var
= 0
movea 0x006F, $5, $5 ;GY = 0x6F (Screen)
st.h $5, 6[$1]
mov 16, $5
;W =
16
st.h $5, 14[$1]
st.h $5, 16[$1] ;H = 16
movhi 0x3DBC, $0, $1 ;Load 30 World Address
shr 12, $1
;Alias: 0003DBC0
xor $5, $5
;Var
= 0 , Again? :)
mov 0x40, $5
;0x0040...End
st.h $5, 0[$1] ;Load World
Desc Part
Well, after doing all this stuff, we only need the palette
values... I'll not discuss right now anything about the palettes, for now, use the
following:
movhi 0x05F8, $0, $1
;Get a pointer to the VIP Reg
shr 8, $1
;Address: 0005F800
mov 0x0C, $2 ;Load
the Color Intensity
st.h $2, 0x24[$1] ;BRTA
add 0x0C,$2
st.h $2, 0x26[$1] ;BRTB
add 0x0C,$2
st.h $2, 0x28[$1] ;BRTC
xor $2, $2
movea 0xE4, $2, $2 ;Pallette Value: 11100100b
st.h $2, 0x60[$1] ;GPLT0
st.h $2, 0x62[$1] ;GPLT1
st.h $2, 0x64[$1] ;GPLT2
st.h $2, 0x66[$1] ;GPLT3
st.h $2, 0x68[$1] ;JPLT0
st.h $2, 0x6A[$1] ;JPLT1
st.h $2, 0x6C[$1] ;JPLT2
st.h $2, 0x6E[$1] ;JPLT3
st.h $0, 0x70[$1] ;BKCOL
If everything's all right you will see you 3D Box in the Virtual
Boy.

In future references we'll talk about palletes, objects, animation
stuff, special fx, using pad, using interrupts and other things about programming the
Virtual Boy. Thanks to David Tucker and it's page for provides me the needed documentation
of this reference.
|