OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Nov 29, 2022 10:57 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: Change VGA font
PostPosted: Sun May 27, 2012 1:26 am 
Offline
Member
Member

Joined: Sun May 27, 2012 1:00 am
Posts: 45
Location: Russia
Hi!

I've read this:
viewtopic.php?f=1&t=20862
http://www.osdever.net/FreeVGA/vga/vgafunc.htm
and wanted to program VGA font loading in my OS.

Here is my code:

Code:
#include <system.h>
#include <inline.h>

#define COLUMNS 80
#define ROWS 25
#define VIDEO_ADDR 0xB8000

/* @iport - index port, @iport + 1 - data port */
static inline void vga_write_reg(u16_t iport, byte_t reg, byte_t val){
   to_port_b(iport, reg); /* Select register */
   to_port_b(iport + 1, val); /* Do writing through data port */
}
/* @iport - index port, @iport + 1 - data port */
static inline byte_t vga_read_reg(u16_t iport, byte_t reg){
   to_port_b(iport, reg); /* Select register */
   return from_port_b(iport + 1); /* Do reading through data port */
}

#define VGA_SEQ_INDEX_PORT 0x3C4
#define VGA_SEQ_DATA_PORT 0x3C5

#define VGA_GC_INDEX_PORT 0x3CE
#define VGA_GC_DATA_PORT 0x3CF

#define VGA_CRTC_INDEX_PORT 0x3D4
#define VGA_CRTC_DATA_PORT 0x3D5

#define VGA_SEQ_MAP_MASK_REG 0x02
#define VGA_SEQ_CHARSET_REG 0x03
#define VGA_SEQ_MEMORY_MODE_REG 0x04

#define VGA_GC_READ_MAP_SELECT_REG 0x04
#define VGA_GC_GRAPHICS_MODE_REG 0x05
#define VGA_GC_MISC_REG 0x06

#define BYTES_PER_GLYPTH 16
#define BYTES_SKIP 16
#define CHARSET_LENGTH 256
#define FONT_SIZE CHARSET_LENGTH * BYTES_PER_GLYPTH

static void set_font(unsigned char font[FONT_SIZE]){
   int i, j;
   unsigned char *p = (unsigned char *)0xB8000;
   byte_t mem_mode, graphics_mode;
   
   /* Panel 2 write enable */
   vga_write_reg(VGA_SEQ_INDEX_PORT, VGA_SEQ_MAP_MASK_REG, 0x04);
   
   /* To be shure, that the first font in the plane 2 is selected */
   vga_write_reg(VGA_SEQ_INDEX_PORT, VGA_SEQ_CHARSET_REG, 0x00);
   
   mem_mode = vga_read_reg(VGA_SEQ_INDEX_PORT, VGA_SEQ_MEMORY_MODE_REG);
   vga_write_reg(VGA_SEQ_INDEX_PORT, VGA_SEQ_MEMORY_MODE_REG, 0x06);
   
        /* I think this line is unnecessary */
   vga_write_reg(VGA_GC_INDEX_PORT, VGA_GC_READ_MAP_SELECT_REG, 0x02);
   
   graphics_mode = vga_read_reg(VGA_GC_INDEX_PORT, VGA_GC_GRAPHICS_MODE_REG);
   vga_write_reg(VGA_GC_INDEX_PORT, VGA_GC_GRAPHICS_MODE_REG, 0x00);
   
        /* And this line is unnecessary too, since I now, that address is 0xB8000 */
   vga_write_reg(VGA_GC_INDEX_PORT, VGA_GC_MISC_REG, 0x0C);
   
   /* Write charmap */
   for(i = 0; i < CHARSET_LENGTH; i++){
      for(j = 0; j < BYTES_PER_GLYPTH; j++){
         *p = *font;
         ++p;
         ++font;
      }
      p += BYTES_SKIP;
   }
   
   /* Restore VGA to normal operation */
   
   /* Panels 0 and 1 write enable */
   vga_write_reg(VGA_SEQ_INDEX_PORT, VGA_SEQ_MAP_MASK_REG, 0x03);
   vga_write_reg(VGA_SEQ_INDEX_PORT, VGA_SEQ_MEMORY_MODE_REG, mem_mode);
   
   vga_write_reg(VGA_GC_INDEX_PORT, VGA_GC_READ_MAP_SELECT_REG, 0x00);
   vga_write_reg(VGA_GC_INDEX_PORT, VGA_GC_GRAPHICS_MODE_REG, graphics_mode);
   vga_write_reg(VGA_GC_INDEX_PORT, VGA_GC_MISC_REG, 0x0C);
}


I tried this on bochs and real PC, but the font doesn't change! OK, I copied and pasted the code from viewtopic.php?f=1&t=20862, but the same - the font stay unchanged. I breaked my mind, but I can't guess what's wrong.

Please, I need help.

P.S: If it is important: I'm working in the 32-bit protected mode.


Top
 Profile  
 
 Post subject: Re: Change VGA font
PostPosted: Sun May 27, 2012 4:57 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9301
Location: On the balcony, where I can actually keep 1½m distance
I checked the register writes and couldn't find anything wrong within the posted code.

What actually is your custom font? The ready-to-use fonts you find on the web are typically the same as what you already have in video memory - which means there is no change to be expected.

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: Change VGA font
PostPosted: Sun May 27, 2012 5:22 am 
Offline
Member
Member

Joined: Sun May 27, 2012 1:00 am
Posts: 45
Location: Russia
Thank you for reply,

I took /usr/share/kbd/consolefonts/koi8r-8x16.gz (4096 bytes long) from my Linux installation, unpacked it and transformed into font.c file: unsigned char font[] = {0x00, ...}.

Bochs VGA BIOS's font isn't equal to koi8r-8x16.gz, since I've tried 2 Bochs (on my Linux host and my Windows host) with different VGA BIOS's fonts.

Any ideas?


Top
 Profile  
 
 Post subject: Re: Change VGA font
PostPosted: Sun May 27, 2012 6:45 am 
Offline
Member
Member

Joined: Sun May 27, 2012 1:00 am
Posts: 45
Location: Russia
OK, I've tried to load garbage instead of a font on a real PC... but nothing changed!

1) I begin write font from address 0xB8000 and no outputed text on my console become corrupted, so I can assume that I really write to plane 2 of VGA memory.

2) I programed exactly the same function as set_font(): get_font(). And tried: set_font(my_font), get_font(temp_buffer), memcmp(my_font, temp_buffer). And my_font and temp_buffer were the same. So, I can assume that I really write my font to plane 2.

3) In set_font() I set the value of Character Set register of the Sequencer to 0x00 - so Character Set A and Character Set B points to 0x0000 - 0x1FFF (where I write my font).

What I should do? What values I should check?
May be I something miss in theory of font loading in VGA?
May be GRUB (that I use to load my kernel) switches something in VGA?


Top
 Profile  
 
 Post subject: Re: Change VGA font
PostPosted: Sun May 27, 2012 9:14 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9301
Location: On the balcony, where I can actually keep 1½m distance
I just converted your code to something I could actually run and came up with the following bit of bootsector code:
Code:
        MOV AX, 0xB800
        MOV ES, AX

        MOV DX, 0x3C4
        MOV AX, 0x0402          ; seq.mapmask = !0, !1, 2, !3
        OUT DX, AX
        MOV AX, 0x0003          ; seq.font A=0 B=0
        OUT DX, AX
        MOV AX, 0x0604          ; seq.memmode = O/E off, chain4 off, ext on
        OUT DX, AX

        MOV DX, 0x3CE
        MOV AX, 0x0005          ; gx.modereg = !256, !shift, !OE, writemode_0
        OUT DX, AX
        MOV AX, 0x0C06          ; gx.miscreg = map_b8000, !HostOE, !graphics
        OUT DX, AX

        ; set font to garbage
        MOV CX, 0x1000
        XOR DI, DI
.loop:  MOV AL, CL
        MOV [ES:DI], CL
        INC DI
        DEC CX
Which worked as expected. Note that gx[6] = 0x0C doesn't just fix the write address, but also fixes the Odd/Even bit to a known value, so I'd probably keep that. The read map is only needed for reading.

At any rate, I have absolutely no reason left to believe the error is in the code posted. But since reading and writing responds like actual memory, I suspect that you're not actually hitting video memory (or even overwriting it later). What are your paging and segment configurations like? Can you enable debug logging of bochs' VGA plugin and check that the port writes are actually performed as expected?

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: Change VGA font
PostPosted: Tue May 29, 2012 3:24 pm 
Offline
Member
Member

Joined: Sun May 27, 2012 1:00 am
Posts: 45
Location: Russia
Combuster, thank you for your help. Now I realized that my code loading font is right and the problem was in: 1) I used bochs in linux console (not X-System) => font changes were impossible, 2) I used this code to check that the font has been changed:

Code:
puts("Old font:\n");
for(i = 0; i < 256; i++)
putchar(i);
set_font(my_font);
puts("\nNew font:\n");
for(i = 0; i < 256; i++)
putchar(i);


This check is wrong, but I realize it only now. I'm ashamed of myself.

Now all is OK, and I did a funny trick: I took a monochrome bmp-file, divided it into small glyphes and loaded them as font in text mode 80x25. Screenshot of the result you can see in the attachment. I think the result is not bad.


Attachments:
che_in_bochs.PNG
che_in_bochs.PNG [ 20.39 KiB | Viewed 6580 times ]
Top
 Profile  
 
 Post subject: Re: Change VGA font
PostPosted: Tue May 29, 2012 5:10 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9301
Location: On the balcony, where I can actually keep 1½m distance
You're welcome.

suslik wrote:
I think the result is not bad.
For a quick improvement on the character art, set the 9/8 dot mode register to 8 to remove the red lines, and set the dot clock to 25 MHz to prevent real screens from complaining about the altered frequency. :wink:

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: Change VGA font
PostPosted: Wed May 30, 2012 3:22 am 
Offline
Member
Member
User avatar

Joined: Tue Feb 08, 2011 1:58 pm
Posts: 496
suslik wrote:
Screenshot of the result you can see in the attachment. I think the result is not bad.

You can make it better if you turn off 9th pixel (instead of 9x16 you'll have 8x16 characters). That will make those vertical lines disappear.


Top
 Profile  
 
 Post subject: Re: Change VGA font
PostPosted: Wed May 30, 2012 9:27 pm 
Offline
Member
Member

Joined: Sun May 27, 2012 1:00 am
Posts: 45
Location: Russia
OK, I did it. Much better, you are right. BUT: without those vertical lines there is no mention of the text mode, 'Che' looks like in graphics mode now. I think some difference should be to proof everyone that this is text mode.


Attachments:
che_in_bochs_2.PNG
che_in_bochs_2.PNG [ 18.08 KiB | Viewed 6496 times ]
Top
 Profile  
 
 Post subject: Re: Change VGA font
PostPosted: Thu May 31, 2012 5:41 am 
Offline
Member
Member

Joined: Tue Nov 08, 2011 11:35 am
Posts: 453
Use less than 256 chars for tiles. The best variant is to leave as much from standard font as possible, rendering the picture with mostly standard characters. Dithering is your friend.
Then you can add some text in free space of the screen.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot], PetalBot [Bot] and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group