I have a variable that is called average
and in my DATASEG
, it changes every time because the user enters a different input every time. What I want to do is to go to the graphics mode (VGA) and then print there Your average is: and then the average I know how to change to the graphics mode like this:
mov ax, 13h
int 10h
After printing the average I want to print below if the average is above 75 You are a good student, keep up the good work and if not. Don't worry you will get better! Thanks in advance.
I am assuming: PC VGA x86 MS DOS platform
It does not really matter if real or emulated unless you want low level IO access which might not work properly on emulation like DOSBOX ...
Video/Text modes
So to switch between video and text modes you need to use VGA BIOS:
There are many video modes here two very important ones:
In video mode
19
you print/peek pixel by accessing memory at segmentA000h
where offset is computed like this:The
320x200
mode fits entirely into64 KByte
segment so you do not need to switch pages. This makes it ideal for simple asm gfx programs ....Mode
3
is text mode where each character has2 BYTEs
one is color and the other is extended ASCII code. Again print/peek is done by accessingWORD
at segmentB800h
where offset is:Not sure what order is the two bytes in anymore it was ages ago but you can easily test if writing
A
at0B800:0000
will renderA
in top left corner or0B800:0001
instead. IIRC colors in text modes are just first 16 colors from palette and the color byte encodes ink paper brightness and flash. This text mode is also the default mode your MS-DOS shell is working in so you should set it back before program exit.So your program should look like this:
Printing strings
For starters you can combine text and video modes ... Like I do here:
it is a simple game where menus are in text mode (where printing is easy and just matter of copying the string into VRAM) and the sprite graphics game is on
320x200x256c
video mode.When you want to print in gfx mode you first need to have some Font in the memory. If you look at the EGA/VGA BIOS documentation you can obtain the font located in EGA/VGA ROM and use directly that. I also created this image (IIRC using Trident 9000 256/512KB VGA font) which I use as a mono-spaced font for OpenGL and other stuff (where accessing VGA BIOS is not possible or wanted)...
Here GLSL example of using it for printing You can port it to CPU/VGA/asm but the printing on CPU is much more simpler no need for such horrible things like in GLSL fragment.
So you just need to compute image position from ASCII code and copy its pixels into VRAM. Of coarse having bitmap in asm is not easy and much easier is to have it directly in binary form (as set of
db
) so you can write some simple C++ (or whatever) script which loads image and converts it to asm source ...Here is some ancient
320x200x256 colors
printing lib I wrote in NASM ages ago (using EGA/VGA Font directly):So to use it the program should be like:
The
print
is used by settingds,si
so it points to your null terminated string. As you can seeprintl
does not need that as it uses string located directly after theprintl
call and program continues after it ... This way you do not need pointer setting instructions nor any additional labes ... The colors are incl,ch
one is ink and the other is paper. Ifcl==ch
then no paper will be rendered just the ink pixels that is useful if you got image or gfx background behind the text ... The values for colors might not be visible I taken the colors from one of mine games which sets its own palette so if nothing is visible try to set differentcl,ch
likemov cx,0305h
Take a look at this:Print numbers
Printing non negative integer number value is a matter of dividing the number by base (10) and printing the
remainder + '0'
in reverse order as characters ...In
hex
it is even easier as each digit corresponds to nibble<0-15>
so for 16 bit in you take highest 4 bits convert to char either byxlat
table or by adding'0'
or'A'
depending if value is below10
... so no divisions just bit shift/mask ... print the char and shift left the value by 4 bits to process next digit ...btw in gfx modes is often much nicer and user friendly to instead of printing a value as a number render a progress bar like stuff instead which is much much more easier ... collapses to single loop rendering H or V line ... like
REP STOSB
:) ...