Visit The new RRC2Soft Tutorials ^_-

We made available new tutorials in Enjoy!

INTRO: Graphic mode 320x200x256

      In this lesson we'll see the basics of working in a graphics mode: How to put the 320x200x256 mode, how to exit of it, how to draw pixels, how to use the palette,...Well, all the basics, like i said.
      Of course, most of the code is programmed in Asm, for optimization (we need speed in graphics mode).

Before start
Basics of 320x200x256 Mode
Put some colors into your life
Vertical retrace
Behind Scenario: Virtual Screens
Source Code


      Segment and offset

      Memory in Intel 80x86 in real mode (MS-DOS) use segment:offset to access to one byte. This means that if i want to put/get a byte in memory, i must give these two values, instead of a linear address.
      Segment and offset are usually in hexadecimal.
      Segment:Offset is equivalent to (Segment*16)+Offset.
Example:A000h:0001h it's 655361 (in linear address).
      MS-DOS can't take a byte above F000:FFFF->FFFFF-> nearly 1Mb. This's THE barrier. If we want to use the addresses above 1Mb, we need to use EMS or XMS. Or protected mode. Or Win95 + DirectX.


      Communications between programs and Hw (video cards, HDD controllers,...) are done by ports. If i want to send/receive data to/from Hw we need to use ports.
      In Pascal, ports are a predefined arrays: PORT y PORTW. One manages 8 bits ports, and the another manages 16 bits ports.

BASICS OF 320x200x256 MODE

      How to start (and end) the 13h mode

      For start the 320x200x256 mode (13h), interrupts are a must. We make a call to interrupt 10h (screen services). Inside this interrupt we use service 0h (active a graphics mode) with parameter 13h (mode 13h). And voilà!!!, we're in 320x200x256.
      (If you don't know anythng of assembler, no problem. The only important thing is to use the code, not know how are made).
      Code: [ mov ah,0; mov al,13h; int 10h ]
      For exit, we use the same interrupt and service, but with parameter 03h (text mode)

      Pixels. Where are, and how to change them

      In every graphics mode, screen is "mapped" on memory. This mean that one pixel in the screen is one byte in memory.
      How? in this way:

MEMORY (64000 contiguous bytes starting in DESPLZ)


SCREEN (320 columns and 200 rows)


      There's an equivalence between memory and screen: DESPLZ:(320*row)+column<=>(row,column)
Example: one pixel in row 1, column 2, it's in DESPLZ:(320*1)+2=DESPLZ:322.
      And what is DESPLZ ? Segment A000h. So, the first position of the screen in memory is the byte A000h:0000h.
      Then, If i want to draw one pixel of color P (one pixel is a byte=[0..255] -> you know now why we have 256 colors  ^_^) in row R, column C, i must make one operation:
      Now we have color P in row R, column C of the screen.


      RGB. Palette

      As you know, one color is made by mixing other colors.
For example: black is the mix of no colors, white is the mix of all the colors, and violet is red+blue.
      In PC, the mechanism is the same (mix colors). Every color is the combination of some basic colors.
      In 320x200x256 mode, colors are red, el green and blue. So RGB=R(ed)G(reen)B(lue).
      These three colors have 64 degrees of intensity (0..63) (this is cuz we use 6 bits for intensity: 26). When we join these intensities, we obtain one color (R,G,B):

Example: red (63,0,0) joins blue (0,0,63) and violet is the result (63,0,63) ^_^
(R=63,G=0,B=0) (R=0,G=0,B=63) (R=63,G=0,B=63)

      Palette is a set of colors (in this mode 256), and everyone is made with the method described above (combination Red.Green-Blue). We can say that we have an array of 256 elements, and one element is the result is three intensities: (R[0..63],V[0..63],A[0..63]).


      Where's the palette?. Here.
      DAC is a Digital to Analogic Converter. It converts RGB intensities to colors in the screen (said fast and not very well ^_^).
      It has 256 registers of 18 bits (<-palette), and every one of these registers has the RGB intensities. When in screen we draw the pixel x (23, f. ex.), x is the index to one of the DAC registers.

      DAC Ports

      DAC has some ports, and through them we can read/write the RGB intensities of every color:

3C7h (Pel Read Address) Index to a color to access(0..255)
3C8h (Pel Write Address) Index to a color to change(0..255)
3C9h (Pel Data DAC) Access to a DAC register

      How to use DAC ports and BIOS to change the intensity of colors.

      Read a DAC register (read the RGB components of a color):
      Set in port 3C7h the color to be accessed. Next we read three times the port 3C9h, and we obtain the RGB components (1º red, 2º green y 3º blue).

      Change a DAC register (write the RGB components of a color):
      Set in port 3C8h the color to be changed. Next we write in 3C9h the RGB components (1º red, 2º green y 3º blue, three writes).

      Change an entire palette (using BIOS interrupts):
      (I suppose we have a var. called Palette => Array 0..255 of r,g,b:byte).
      Use interrupt 10h, service 10h, subfunction (al) 12h (change DAC components).Bx=0 (start in the first color, 0), Cx=256 (change 256 colors), Es:Dx=Seg(Palette):Ofs(Palette) (Segment and Offset of variable palette).
      NOTE: the record r,g,b:byte is in this order 'cause system takes the first component of the record as R, second as G and third as B.

      (Thanks to PCActual magazine and to Antonio Ropero)


      The image in screen bring up-to-date its contents from video memory, $A000:0000 (this can't be saw by human eyes, but videocameras can: try to film your monitor).
      And how happens? An electron beam starts in the first line of the upper left corner, and goes to the right. When it arrives into the edge of the right, goes to the next line. It ends in the lower right corner. (see that the beam starts in the start of video memory and ends in the end of video memory. Look at tables in Pixels. Where are, and how to change them).
      This process is iterative.

      What is Vertical retrace?

      When the beam arrives to the lower right corner, it goes to the upper left corner. This moment is called  vertical retrace.

      What problems have?

      The vertical retrace have no problems ^_^. But the beam has: If we draw an sprite in the screen when the beam is working, the sprite may flick (cuz not the entire image'll be draw, only the part after the beam).
Example: if we draw an sprite $A000:3FF0 a $A000:4005 and the beam is in $A000:4000, only the range of pixels $A000:4000=>$A000:4005 will be displayed (the other pixels of the sprite must wait the next beam).

      How can I avoid flickering?

      Waiting the vertical retrace. In this moment the beam will be in $A000:0000 and every pixel we draw will be put onto screen.
      And V.R. has another good thing: makes an universal delay for every computer (cuz V.R. not depends on microprocessor Mhz).


      What are virtual screens?

      Remember that screen is mapped in memory (1 pixel=>one byte in video memory). Well then, a virtual screen is a variable that imitates the structure of video memory (Array[0..63999] of byte).
      If we imitate the structure of video memory, we can "draw" pixels (write bytes) onto this "screen", using the segment of the virtual screen: SegVirtual:[(320*R)+C]. Of course every "pixel" in this "screen" won't be wrote in the real screen.

      How can i use them

      If we draw the scenario and the sprites in the real screen, the gift will be a brutal flickering.

      So we draw the pixel onto the virtual screen, wait the vertical retrace and flip the contents of the virtual screen onto memory. (We copy the 64000 bytes of [$A000:0000,$A000:FFFF]).
      Then, there'll be no flick with this method.

      In future...

      Virtual screens have more uses: scrolls, backups,...etc. See the next lessons of this tutorial.


      In the .zip with the game there's two files: G320x200.pas and virtuals.pas. They have the routines of all the things explained in this file, with more things

        Well, its 3:35 am, i want to sleep,... Why i don't use a translator like everybody in this world ?. I suppose i'm a @·$%¿?!, but translators are @#!#?¡# ....^_^. 1