Page 2 of 3
Re: Printing strings in graphics mode (320x200)
Posted: Tue Jul 06, 2010 3:19 am
by Benjamin1996
Creature wrote:Or you could use a
bitmap version of the Bochs font instead and load that from disk (or through multiboot modules). But it's probably faster to do it through the BIOS (no disk loading involved, so no errors can occur following from that).
Thanks, but I think I'll just stick with the fonts the BIOS can provide through interrupts
.
Re: Printing strings in graphics mode (320x200)
Posted: Tue Jul 06, 2010 11:12 am
by Benjamin1996
To start off, here's a screenshot of me trying to implement the 8x14 font in 320x200 screen resolution, provided by the BIOS:
This is my main routine:
Code: Select all
chooseBootingMode db "Would you like to perform a verbose boot?", 0x000d, 0x000a, 0
main:
xor ax, ax
mov ds, ax
call mode13h ;Enter mode 13 (320x200)
call clearScreen ;Clear screen by writing 0s to a000
call getFont
mov si, chooseBootingMode
call printString
jmp $
This is the 'getFont' + 'printString' function:
Code: Select all
getFont:
mov ax, 0x1130
mov bh, 0x0002
int 0x0010
push es
pop ds
mov si, bp
push cs
pop es
mov di, fontBuffer
mov cx, 256
populateBuffer:
movsw
movsw
movsw
movsw
movsw
movsw
movsw
movsw
loop populateBuffer
mov bp, fontBuffer
xor dx, dx
mov cx, 256
mov bh, 16
mov bl, 1
mov ax, 0x1100
int 0x0010
mov bx, 0x0100
mov cx, bx
shl bh, 2
or bl, bh
mov ax, 0x1103
int 0x0010
mov bx, 0x0f12
cmp cl, ch
jz short update
mov bh, 0x0007
update:
mov ax, 0x1000
int 0x0010
ret
printString:
mov ah, 0x000f
int 0x0010
mov ah, 0x0003
int 0x0010
print:
lodsb
cmp al, 0
je printed
mov ah, 0x000e
mov bh, 0x0000
mov bl, 0x0007
int 0x0010
jmp print
printed:
ret
I'm pretty sure this is a common problem trying to accomplish what I'm trying to.. yet, I can't seem to find any info or solutions for this problem.
Please help me
.
Re: Printing strings in graphics mode (320x200)
Posted: Tue Jul 06, 2010 3:56 pm
by Gigasoft
First of all, you're loading the font into video RAM while in graphics mode. What would that be good for? You're just overwriting certain columns on the screen. Then you set the block specifier, which does nothing in graphics mode. Then you enable color planes 0, 1 and 2 but not 3 (why?).
Then, when printing, you retrieve the current cursor position and size and do nothing with it before you try to print the string (with DS still pointing at the video ROM and with the controller set to the wrong addressing mode after trying to load the font).
You don't need to retrieve or set any fonts to print characters using the BIOS. You only need to retrieve the font if you intend to draw characters manually without using the BIOS.
Re: Printing strings in graphics mode (320x200)
Posted: Tue Jul 06, 2010 3:59 pm
by Combuster
Time to plug a reference to
bochs' debugger. Since you consider yourself expert enough to develop an os, you know how to use it
Re: Printing strings in graphics mode (320x200)
Posted: Wed Jul 07, 2010 7:46 am
by Benjamin1996
Gigasoft wrote:First of all, you're loading the font into video RAM while in graphics mode. What would that be good for? You're just overwriting certain columns on the screen. Then you set the block specifier, which does nothing in graphics mode. Then you enable color planes 0, 1 and 2 but not 3 (why?).
Then, when printing, you retrieve the current cursor position and size and do nothing with it before you try to print the string (with DS still pointing at the video ROM and with the controller set to the wrong addressing mode after trying to load the font).
You don't need to retrieve or set any fonts to print characters using the BIOS. You only need to retrieve the font if you intend to draw characters manually without using the BIOS.
To be honest, it isn't much of your reply that makes any sense to me, Gigasoft. Maybe because I have a major headache, I don't know..
BUT, a lot of things did come to my mind reading your reply. Like how much of the code I actually wrote "without thinking about it". Firstly, I remembered that I'm in mode 13h, not mode 12h. Therefore, I don't have to use bit planes, as they're only present in mode 0dh, 0eh, 10h, and 12h. Secondly, after you stating that I didn't take use of the cursor size & position and the video mode I retrieved from the interrupts at the top of my 'printString' function, the penny finally fell. I had wrote my 'printString' function the way I usually do it in text-mode, when I was actually supposed to use function number 13h. The problem probably is I wrote this function when it was like 2:30 AM in Denmark. My bad.. anyway, with my new code the problem is that it simply doesn't print out anything.
Here's the code:
'main' routine:
Code: Select all
chooseBootingMode db "Would you like to perform a verbose boot?", 0x000d, 0x000a, 0
main:
xor ax, ax
mov ds, ax
call getFont
call mode13h
call clearScreen
mov bp, chooseBootingMode
call printString
jmp $
'getFont' & 'printString':
Code: Select all
getFont:
mov ax, 0x1130
mov bh, 0x0002
int 0x0010
push es
pop ds
mov si, bp
push cs
pop es
mov di, fontBuffer
mov cx, 256
populateBuffer:
movsw
movsw
movsw
movsw
movsw
movsw
movsw
movsw
loop populateBuffer
mov bp, fontBuffer
xor dx, dx
mov cx, 256
mov bh, 16
mov bl, 1
mov ax, 0x1100
int 0x0010
mov bx, 0x0100
mov cx, bx
shl bh, 2
or bl, bh
mov ax, 0x1103
int 0x0010
ret
printString:
mov ah, 0x000f
int 0x0010
mov ah, 0x0003
int 0x0010
mov cx, 44
mov bl, 0x0007
mov ax, 0x1301
int 0x0010
ret
fontBuffer:
Re: Printing strings in graphics mode (320x200)
Posted: Wed Jul 07, 2010 8:15 am
by Gigasoft
Well, the essential problems I was trying to point out were:
- Using a text mode font upload service while in graphics mode. This causes screen corruption, since plane 2, where the text mode font resides while in text mode, now contains pixels. More importantly, the BIOS will set the card back to text mode addressing after uploading the font, so that further accesses to the display memory will affect the wrong memory locations.
- When you print the string, DS points to the wrong segment. It points to the ROM font's segment instead of your own segment.
Re: Printing strings in graphics mode (320x200)
Posted: Wed Jul 07, 2010 8:22 am
by Benjamin1996
Gigasoft wrote:Well, the essential problems I was trying to point out were:
- Using a text mode font upload service while in graphics mode. This causes screen corruption, since plane 2, where the text mode font resides while in text mode, now contains pixels. More importantly, the BIOS will set the card back to text mode addressing after uploading the font, so that further accesses to the display memory will affect the wrong memory locations.
- When you print the string, DS points to the wrong segment. It points to the ROM font's segment instead of your own segment.
I was aware of the thing 'bout DS. but I wasn't aware of the things you said about the BIOS, so thanks for enlightening me
. So with my newest code (which you can see in the post above yours) I'll have to call the mode13h function to make the switch after I did the "text-mode related" stuff, and after I 'uploaded' the font?
EDIT: Nope, no changes if I move the 'call mode13h' call from the 'main' routine to right above the 'ret' statement in the 'getFont' function (if that's what you meant).
Re: Printing strings in graphics mode (320x200)
Posted: Wed Jul 07, 2010 9:22 am
by Gigasoft
Well, no. I'm not sure why you're trying to upload the font. That would only be useful in text mode. When changing to graphics mode, the font is erased because the memory is used for something else. The block specifier is also meaningless in graphics mode.
To change the font used to print text in graphics mode, you should use one of the functions 1120h through 1124h. This should be done after switching to graphics mode.
Re: Printing strings in graphics mode (320x200)
Posted: Wed Jul 07, 2010 9:42 am
by Benjamin1996
Gigasoft wrote:Well, no. I'm not sure why you're trying to upload the font. That would only be useful in text mode. When changing to graphics mode, the font is erased because the memory is used for something else. The block specifier is also meaningless in graphics mode.
To change the font used to print text in graphics mode, you should use one of the functions 1120h through 1124h. This should be done after switching to graphics mode.
So would I be able to (to get a first time example going) go into mode 13h, then use function 1130h of int 10h to move a pointer to the specified font bitmap into ES:BP, and right after that make a call to function 1120h of int 10h, to apply the bitmap pointed to by ES:BP, and then use the standard character/string printing functions of the BIOS to print a string?
Re: Printing strings in graphics mode (320x200)
Posted: Wed Jul 07, 2010 1:16 pm
by Gigasoft
Well, almost. Function 1120h is for loading an 8x8 font, so it should be function 1121h (or function 1122h to use the ROM 8x14 font.)
And you should make sure you don't print beyond the right side of the screen with function 13h, because the text will continue on the next screen row instead of advancing by the correct number of rows (the character height).
Re: Printing strings in graphics mode (320x200)
Posted: Wed Jul 07, 2010 1:51 pm
by Benjamin1996
Gigasoft wrote:Well, almost. Function 1120h is for loading an 8x8 font, so it should be function 1121h (or function 1122h to use the ROM 8x14 font.)
And you should make sure you don't print beyond the right side of the screen with function 13h, because the text will continue on the next screen row instead of advancing by the correct number of rows (the character height).
Well, of course.
But my problem is that my doesn't print out anything!
This is really starting to wear on my nerves!
'main':
Code: Select all
chooseBootingMode db "Would you like to perform a verbose boot?", 0x000d, 0x000a, 0
main:
xor ax, ax
mov ds, ax
call mode13h
call getFont
call clearScreen
mov bp, chooseBootingMode
call printString
jmp $
'getFont' + 'printString':
Code: Select all
getFont:
mov ax, 0x1130
xor bh, bh
int 0x0010
mov ax, 0x1120
int 0x0010
ret
printString:
mov ah, 0x000f
int 0x0010
mov ah, 0x0003
int 0x0010
mov cx, 44
mov bl, 0x0007
mov ax, 0x1301
int 0x0010
ret
This doesn't print out anything, AND the cursor is not showing..
Re: Printing strings in graphics mode (320x200)
Posted: Wed Jul 07, 2010 4:33 pm
by Gigasoft
Your getFont function does nothing right now. It basically sets the font used for CGA mode to what it was before.
Does ES point to your segment when calling printString? Try setting DX to 0 before invoking function 13h, just to make sure that this isn't the problem.
And there is no visible cursor in graphics mode. The cursor is only displayed in text mode.
Re: Printing strings in graphics mode (320x200)
Posted: Thu Jul 08, 2010 2:21 am
by Benjamin1996
Gigasoft wrote:Your getFont function does nothing right now. It basically sets the font used for CGA mode to what it was before.
Does ES point to your segment when calling printString? Try setting DX to 0 before invoking function 13h, just to make sure that this isn't the problem.
And there is no visible cursor in graphics mode. The cursor is only displayed in text mode.
Uhhmm.. I decided to use function number 1121h, but it's causing me problems. When I run the following code I get this ear blowing constant BEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEP, that never stops, and the screen is filled with a bunch of garbage, like smilies etc etc..
I assume you're already pretty familiar with my 'main' routine, so I'm just going to tell you the changes: I added a 'xor dx, dx' before the call to 'mode13h'.
Other than that everything in the 'main' routine is the same.
The 'printString' function is also unchanged, so I'll just show you the 'getFont' function.
Code: Select all
getFont:
mov ax, 0x1130
mov bh, 0x0002
int 0x0010
mov ax, 0x1121
mov cx, 256
xor bl, bl
mov dl, 200
int 0x0010
ret
If you're wondering about the values I put in as arguments for the 1121h function, here's an explanation:
*CX should be the amount of bytes per character. As I am in mode 13h (320x200x256) it's value is 256.
*BL should be the row set, I don't know what they mean by that but they said 0 meant user set, so I went with that.
*DL should be the number of rows, as there's 200 rows in mode 13h, I put a 200 in there
.
Re: Printing strings in graphics mode (320x200)
Posted: Thu Jul 08, 2010 7:14 am
by Gigasoft
No, what I meant was xor dx,dx before this (to starting printing a column 0, row 0), not before the call to mode13h:
mov ax, 0x1301
int 0x0010
But now it at least prints something, so that wasn't the problem.
The garbage printed indicates that ES is set to the wrong value when calling printString.
The parameters to function 1121h are wrong. Bytes per character (CX) should be 14. DL should be 01, for 14 text rows (the maximum that will fit in 200 screen rows).
Re: Printing strings in graphics mode (320x200)
Posted: Thu Jul 08, 2010 11:19 am
by Benjamin1996
Gigasoft wrote:No, what I meant was xor dx,dx before this (to starting printing a column 0, row 0), not before the call to mode13h:
mov ax, 0x1301
int 0x0010
But now it at least prints something, so that wasn't the problem.
The garbage printed indicates that ES is set to the wrong value when calling printString.
The parameters to function 1121h are wrong. Bytes per character (CX) should be 14. DL should be 01, for 14 text rows (the maximum that will fit in 200 screen rows).
Nope. Now we're just back to it not printing anything. This is my 'main' routine:
Code: Select all
chooseBootingMode db "Would you like to perform a verbose boot?", 0x000d, 0x000a, 0
main:
xor ax, ax
mov ds, ax
call mode13h
call getFont
call clearScreen
mov bp, chooseBootingMode
call printString
jmp $
'getFont' & 'printString':
Code: Select all
getFont:
mov ax, 0x1130
mov bh, 0x0002
int 0x0010
mov ax, 0x1121
mov cx, 14
xor bl, bl
mov dl, 0x0001
int 0x0010
ret
printString:
xor dx, dx
mov ah, 0x000f
int 0x0010
mov ah, 0x0003
int 0x0010
mov cx, 44
mov bl, 0x0007
mov ax, 0x1301
int 0x0010
ret
Oh and by the way, I have one little convenience question: When I'm in graphics mode, will the position of the cursor still affect where the text is printed even though the cursor is not visible?