text size
text size
I'm writing my OS mostly in C because I don't know assembly well enough to do so. Since I'm using C, is there any way to change the size of the text. I have seen Smiddy's OS and it looks freaking awsome with the smaller font. I was wondering on how to do that in C. Thanks in advance for your help.
-
- Member
- Posts: 83
- Joined: Fri Oct 22, 2004 11:00 pm
Re: text size
Size of text? That is not such an easy task to do... I can think of basically two ways.
1. Change the screen resolution. This way the text size will be smaller (or bigger). The problem with this, is that you have to adjust everything else, and you can only have one type of text size.
2. Make your own font. The problem with this is that you have to make a font file, need to get your os to open the file and understand it, and you need you need to be able to support a graphics resolution to display it.
Your choice of what to pick if you really want that...
1. Change the screen resolution. This way the text size will be smaller (or bigger). The problem with this, is that you have to adjust everything else, and you can only have one type of text size.
2. Make your own font. The problem with this is that you have to make a font file, need to get your os to open the file and understand it, and you need you need to be able to support a graphics resolution to display it.
Your choice of what to pick if you really want that...
- smiddy
- Member
- Posts: 127
- Joined: Sun Oct 24, 2004 11:00 pm
- Location: In my cube, like a good leming. ;-)
Re: text size
Thanks for the complement. It is quite simple, though I should warn you first. I setup that text mode prior to going into protected mode. It is INT 10h AX=4F02h BX=10Ch... OK, so that gives that away, but what is it? Can I do more, etcetera. I found this information in Barry Brey's book The Intel Microprocessor 8086/8088, 80186/80188, 80286, 80386, 80486, Pentium, Pentium Pro Processor, Pentium II, Pentium III, Pentium 4 Archetecture, Programming, and Interfacing (Sixth Edition). There is a section in it that describes SVGA and EVGA. The extended VGA (EVGA)functions are as tabulated:
While this isn't all encompassing, it should give you a start on some decisions you intend to make with your own. I assume that you can call BIOS from within C, and that you go from real to protected mode within your code?
BTW, so you are aware, and in case your screen shows up as 90 x 60 text mode, I check to ensure that this mode works by looking at the BIOS Data Area at linear address 44Ah for the number of columns as this call updates the number of columns. If it doesn't work, or isn't 132, then I revert to Chris Geise's code 90x60.asm, which you can get from his web site. It is assembly code too and doesn't require that you be in real mode, as it tickles the VGA ports directly. It also requires you to research the different VGA registers, of which I have very little knowledge of right now.
I hope that help, and happy coding!
Code: Select all
BX Extended Mode
100h 640 x 400 with 256 colors
101h 640 x 480 with 256 colors
102h 800 x 600 with 16 colors
103h 800 x 600 with 256 colors
104h 1024 x 768 with 16 colors
105h 1024 x 768 with 256 colors
106h 1280 x 1024 with 16 colors
107h 1280 x 1024 with 256 colors
108h 80 x 60 in text mode
109h 132 x 25 in text mode
10Ah 132 x 43 in text mode
10Bh 132 x 50 in text mode
10Ch 132 x 60 in text mode
BTW, so you are aware, and in case your screen shows up as 90 x 60 text mode, I check to ensure that this mode works by looking at the BIOS Data Area at linear address 44Ah for the number of columns as this call updates the number of columns. If it doesn't work, or isn't 132, then I revert to Chris Geise's code 90x60.asm, which you can get from his web site. It is assembly code too and doesn't require that you be in real mode, as it tickles the VGA ports directly. It also requires you to research the different VGA registers, of which I have very little knowledge of right now.
I hope that help, and happy coding!
-smiddy
Re: text size
When I change the font size, do I have to change the text pointer 0xb8000 to something else inorder for it to work? Because I tried:
mov ax, 4F02h
mov bx, 10Ch
int 10h
in my bootloader before I enable the a20 and enter protected mode, and the text stayed the same. Also I have no idea at the moment on how to switch between real and protected mode in C. I'm going to look that info up tonight. I'm in the real early stages of OS dev so if I need to rewrite my C code into assembly for it work right, I'll just do that. I love to code thats why I'm starting to OS dev! Thanks.
mov ax, 4F02h
mov bx, 10Ch
int 10h
in my bootloader before I enable the a20 and enter protected mode, and the text stayed the same. Also I have no idea at the moment on how to switch between real and protected mode in C. I'm going to look that info up tonight. I'm in the real early stages of OS dev so if I need to rewrite my C code into assembly for it work right, I'll just do that. I love to code thats why I'm starting to OS dev! Thanks.
- smiddy
- Member
- Posts: 127
- Joined: Sun Oct 24, 2004 11:00 pm
- Location: In my cube, like a good leming. ;-)
Re: text size
If it didn't work, then your system doesn't support it. Then it is using Chris Giese's code. Did you verify 0040:004A for 132 columns? Other wise you aren't changing. Some code:
You can see from this that I check the columns in the BDA. My CS is equal to 0 (0000) and therefore I make a direct call to memory location 44Ah to see if it has been updated.
Code: Select all
MOV AX,CS ; Save CS (set by DOS or boot loader)
MOV DS,AX ; Save AX into DS
MOV ES,AX ; directly move a value into it
MOV SS,AX ; Stack segment too
MOV AX,TheStackLabel ; The stack works in reverse (Use our stack)
MOV SP,AX ; Point to the top of stack
mov ax,4F02h ; VESA Call
mov bx,10Ch ; 132 x 60 screen size
int 10h ; Call the interrupt
mov al,[es:44Ah] ; Get number of columns
cmp al,132 ; Did it update BIOS communication area?
je .GoodToGo ; Yes, good to go
call ChrisGiese90x60 ; 90 x 60 screen size.
.GoodToGo:
. . .
Last edited by smiddy on Fri Jul 08, 2005 11:00 pm, edited 1 time in total.
-smiddy
Re: text size
When I'm in protected mode and try to do
asm("movl $03h, %ax\n\t"
"int $10h\n\t");
my OS gives me this error: Coprocessor Fault Exception has occured. System Halted!! I belive that I'm using the correct format for inline assembly with gcc. I do that asm() call after I enable my ISRs so thats how I got that error message. When trying to do it in my start up code with nasm syntax
mov ax, 03h
int 10h
it gives just reboots and bochs says that I'm in real mode. So I take it I got some issues with my coding. If ya need to see any code to tell me what I'm doing wrong here let me know. Thanks again.
asm("movl $03h, %ax\n\t"
"int $10h\n\t");
my OS gives me this error: Coprocessor Fault Exception has occured. System Halted!! I belive that I'm using the correct format for inline assembly with gcc. I do that asm() call after I enable my ISRs so thats how I got that error message. When trying to do it in my start up code with nasm syntax
mov ax, 03h
int 10h
it gives just reboots and bochs says that I'm in real mode. So I take it I got some issues with my coding. If ya need to see any code to tell me what I'm doing wrong here let me know. Thanks again.
Last edited by dozerl on Fri Jul 08, 2005 11:00 pm, edited 1 time in total.
- smiddy
- Member
- Posts: 127
- Joined: Sun Oct 24, 2004 11:00 pm
- Location: In my cube, like a good leming. ;-)
Re: text size
You can't call INT 10h from protected mode. INT 10h gets remaped when you go into Protected mode to a Coprocessor Error, thus you are getting what you should by calling INT 10h. This video interrupt routine is only good for realmode. You can go back to real mode and set your IVT to base 0 with a 64kB boundary. Then you can call interrupt 10h video again. But there is a lot of stuff you need to do in order to do this like I mentioned.
Before you go to protected mode, run that code and you should be ok. How are you loading your OS?
Before you go to protected mode, run that code and you should be ok. How are you loading your OS?
-smiddy
Re: text size
I'm loading my OS with GRUB. I switched to it instead of my own bootloader because it was easier to get a memory map and I use GRUB on all my computers.
Last edited by dozerl on Sat Jul 09, 2005 11:00 pm, edited 1 time in total.
- carbonBased
- Member
- Posts: 382
- Joined: Sat Nov 20, 2004 12:00 am
- Location: Wellesley, Ontario, Canada
- Contact:
Re: text size
In other words, you'll have to actually alter GRUB's code to switch text mode before entering pmode.
--Jeff
--Jeff
Re: text size
Ok thanks for the help. I'll dump GRUB then and use my old bootloader and try that code. I'll let ya guys know if I get it.
Re: text size
I used my own bootloader and got the text to change, wahoo. But now I have another problem. My bootloader works fine under Bochs but when I try it under real hardware it just reboots the pc. I looked in the log file from Bochs and it says
00000740566i[FDD ] read() on floppy image returns 0
A bunch of times. What does this mean and how do I go about fixing it. Thanks.
00000740566i[FDD ] read() on floppy image returns 0
A bunch of times. What does this mean and how do I go about fixing it. Thanks.
Re: text size
;==========Begin==========
[bits 16]
[org 0x7c00]
;setting text mode
mov ax, 0x03
int 0x10
mov ax, 0x1112
xor bl, bl
int 0x10
jmp boot
;==========Variables==========
drive DB 0
tracks DB 3
;==========Register Initialization==========
boot:
mov [drive],dl
mov ax,cs
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov sp,0x200
jmp init
;==========Main Function==========
init:
call a20gate
call load
jmp pmode
;==========A20 Initialization==========
a20gate:
cli
mov ax, 0x2401
int 0x15
jc error
sti
ret
;==========Onto Floppy Reading==========
load:
xor ah, ah
mov dl,[drive]
int 0x13
jc load
mov ax,0xffff ;Read in the first track (not including
mov es,ax ;this sector, so only 17 sectors.
mov bx,0x10
mov ah,2
mov al,17
mov ch,0
mov cl,2
mov dh,0
int 0x13
jc load ;error, try again
dec byte [tracks] ;all right, we've got one
mov bx, 0x2210 ;since we only read 17, we only add 0x2200 (length of 17 sectors) to bx
mov ch,0 ;cylinder stays the same
mov dh,1 ;head is changed to 1 (the info on a floppy goes head=0,cyl=0,18 tracks,
;then h=1,c=0,18...h=0,c=1,18...h=1,c=1,18...h=0,c=2,18 etc.
fullread:
mov ax,0xffff ;same segment
mov es,ax
mov ah,2 ;same function
mov al,18 ;now we're reading the entire 18 sectors
mov cl,1 ;starting from sector one (no bootloader to avoid now)
int 0x13
jc fullread ;error try again
dec byte [tracks] ;got another one
cmp byte [tracks], 0 ;if we're done
jz end ;go on into pmode
add bx, 0x2400 ;otherwise, add 0x2400 (the length of 18 sectors) to bx
cmp dh, 1 ;if
jne dhiszero
inc ch
mov dh, 0
jmp continueread
dhiszero:
mov dh, 1
continueread:
jmp fullread
end:
mov dx,0x3F2
mov al,0x0C
out dx,al
ret
pmode:
;==========Into PMODE!==========
cli
mov eax,cr0
or al,1
mov cr0,eax
;==========Load the General Descriptor Table==========
lgdt[GDTR]
;==========Reinitialize all registers for jump into Kernel==========
mov eax,DATASEL
mov ds,eax
mov es,eax
mov fs,eax
mov gs,eax
mov ss,eax
mov esp,0xfffc
jmp CODESEL:switch
[BITS 32]
switch:
jmp CODESEL:0x100000
hlt
;==========DATA (GDT) AREA==========
GDTR:
GDTsize DW GDTEND-GDT-1
GDTbase DD GDT
GDT:
NULLSEL EQU $-GDT
DD 0x0
DD 0x0
CODESEL EQU $-GDT
DW 0xFFFF
DW 0x0
DB 0x0
DB 0x9A
DB 0xCF
DB 0x0
DATASEL EQU $-GDT
DW 0xFFFF
DW 0x0
DB 0x0
DB 0x92
DB 0xCF
DB 0x0
GDTEND:
;==========AND THE BOOT SIGNATURE==========
TIMES 510-($-$$) DB 0
SIGNATURE DW 0xAA55
This is the boot loader for Viridis that I changed abit, since I can't find any good tuts on making my own.
[bits 16]
[org 0x7c00]
;setting text mode
mov ax, 0x03
int 0x10
mov ax, 0x1112
xor bl, bl
int 0x10
jmp boot
;==========Variables==========
drive DB 0
tracks DB 3
;==========Register Initialization==========
boot:
mov [drive],dl
mov ax,cs
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov sp,0x200
jmp init
;==========Main Function==========
init:
call a20gate
call load
jmp pmode
;==========A20 Initialization==========
a20gate:
cli
mov ax, 0x2401
int 0x15
jc error
sti
ret
;==========Onto Floppy Reading==========
load:
xor ah, ah
mov dl,[drive]
int 0x13
jc load
mov ax,0xffff ;Read in the first track (not including
mov es,ax ;this sector, so only 17 sectors.
mov bx,0x10
mov ah,2
mov al,17
mov ch,0
mov cl,2
mov dh,0
int 0x13
jc load ;error, try again
dec byte [tracks] ;all right, we've got one
mov bx, 0x2210 ;since we only read 17, we only add 0x2200 (length of 17 sectors) to bx
mov ch,0 ;cylinder stays the same
mov dh,1 ;head is changed to 1 (the info on a floppy goes head=0,cyl=0,18 tracks,
;then h=1,c=0,18...h=0,c=1,18...h=1,c=1,18...h=0,c=2,18 etc.
fullread:
mov ax,0xffff ;same segment
mov es,ax
mov ah,2 ;same function
mov al,18 ;now we're reading the entire 18 sectors
mov cl,1 ;starting from sector one (no bootloader to avoid now)
int 0x13
jc fullread ;error try again
dec byte [tracks] ;got another one
cmp byte [tracks], 0 ;if we're done
jz end ;go on into pmode
add bx, 0x2400 ;otherwise, add 0x2400 (the length of 18 sectors) to bx
cmp dh, 1 ;if
jne dhiszero
inc ch
mov dh, 0
jmp continueread
dhiszero:
mov dh, 1
continueread:
jmp fullread
end:
mov dx,0x3F2
mov al,0x0C
out dx,al
ret
pmode:
;==========Into PMODE!==========
cli
mov eax,cr0
or al,1
mov cr0,eax
;==========Load the General Descriptor Table==========
lgdt[GDTR]
;==========Reinitialize all registers for jump into Kernel==========
mov eax,DATASEL
mov ds,eax
mov es,eax
mov fs,eax
mov gs,eax
mov ss,eax
mov esp,0xfffc
jmp CODESEL:switch
[BITS 32]
switch:
jmp CODESEL:0x100000
hlt
;==========DATA (GDT) AREA==========
GDTR:
GDTsize DW GDTEND-GDT-1
GDTbase DD GDT
GDT:
NULLSEL EQU $-GDT
DD 0x0
DD 0x0
CODESEL EQU $-GDT
DW 0xFFFF
DW 0x0
DB 0x0
DB 0x9A
DB 0xCF
DB 0x0
DATASEL EQU $-GDT
DW 0xFFFF
DW 0x0
DB 0x0
DB 0x92
DB 0xCF
DB 0x0
GDTEND:
;==========AND THE BOOT SIGNATURE==========
TIMES 510-($-$$) DB 0
SIGNATURE DW 0xAA55
This is the boot loader for Viridis that I changed abit, since I can't find any good tuts on making my own.
Re: text size
Usually I get that "read() on floppy image returns 0" when my image file is too small i.e., Bochs tries to read sectors that don't exist.
- smiddy
- Member
- Posts: 127
- Joined: Sun Oct 24, 2004 11:00 pm
- Location: In my cube, like a good leming. ;-)
Re: text size
I saw several issues within your boot loader. Here I modified it for use with FASM:
I didn't see anything wrong with your track reading, but the EAX for your segments may have been the issue. Try this...let me know how it goes.
Code: Select all
;==========Begin==========
;[bits 16]
DATASEL EQU DataSelector-GDT
CODESEL EQU CodeSelector-GDT
use16 ; FASM compatible
;[org 0x7c00]
org 07C00h ; FASM compatible
BootSector:
;setting text mode
mov ax, 0x03 ; AH=0, AL=3 Set Video Mode
int 0x10 ; Call video interrupt
mov ax, 0x1112 ; AH=11h, AL=12 Load ROM BIOS 8x8 Alpha, Adjust Height EGA, VGA
xor bl, bl ; BL=0 Font block to load
int 0x10 ; Call video interrupt
jmp boot ; Get over the variables
;==========Variables==========
drive DB 0
tracks DB 3
;==========Register Initialization==========
boot:
mov [drive],dl ; Save drive we booted from
mov ax,cs ; Get the code segment from CS to AX
mov ds,ax ; Update DS with CS
mov es,ax ; Update ES with CS
mov fs,ax ; Update FS with CS
mov gs,ax ; Update GS with CS
mov ss,ax ; Update SS with CS (this should go somewhere safer)
mov sp,0x200 ; Update stack pointer with 200h (this isn't a good thing to do)
jmp init ; This is wasted code...jump to init
;==========Main Function==========
init:
call a20gate ; Turn on A20 line for > 1MB RAM access
call loadit ; Load kernel?
jmp pmode ; Go to pmode (turns on protected mode)
;==========A20 Initialization==========
a20gate:
cli ; Turn off interrupts
mov ax, 0x2401 ; AX=2401, Enable A20 line
int 0x15 ; Call interrupt 15h
jc .error ; If carry flag, then it didn't work
jmp .Done
.error:
int 18h ; Funky error do
.Done:
sti ; Turn interrupts back on
ret
;==========Onto Floppy Reading==========
loadit: ; Changed name
xor ah, ah ; AH=0, Reset disk system
mov dl,[drive] ; DL=[drive], assume floppy 0
int 0x13 ; call interrupt 13h
jc loadit ; If an error occurs do it again, forever (this should be set to 3 to 5 times max)
mov ax,0xffff ; Read in the first track (not including
mov es,ax ; Set ES to 0FFFFh <this sector, so only 17 sectors. >
mov bx,0x10 ; Set BX to 10h, this effectively places everything above 1MB
mov ah,2 ; Read disk sectors into memory
mov al,17 ; Number of sectors to read (17 this time, since the first one already read)
mov ch,0 ; Cylinder number
mov cl,2 ; Sector number, sectors start at 1
mov dh,0 ; Head number
int 0x13 ; Call interrupt 13h
jc loadit ; error, try again, forever (this should be set to 3 to 5 times max)
dec byte [tracks] ; Should be down to 2 now <all right, we've got one >
mov bx, 0x2210 ; (17 x 512) + 16 = 2210h <since we only read 17, we only add 0x2200 (length of 17 sectors) to bx >
mov ch,0 ;cylinder stays the same
mov dh,1 ;head is changed to 1 (the info on a floppy goes head=0,cyl=0,18 tracks,
;then h=1,c=0,18...h=0,c=1,18...h=1,c=1,18...h=0,c=2,18 etc.
fullread:
mov ax,0xffff ;same segment
mov es,ax
mov ah,2 ;same function
mov al,18 ;now we're reading the entire 18 sectors
mov cl,1 ;starting from sector one (no bootloader to avoid now)
int 0x13 ; Call interrupt 13h
jc fullread ;error try again (forever?)
dec byte [tracks] ; Should 1 first time, 0 after second time <got another one >
cmp byte [tracks], 0 ;if we're done
jz endload ; changed name <go on into pmode >
add bx, 0x2400 ;otherwise, add 0x2400 (the length of 18 sectors) to bx
cmp dh, 1 ;if DH=1, go chage it
jne dhiszero
inc ch ; Increase cylinder number
mov dh, 0 ; Put DH=0, head
jmp continueread
dhiszero:
mov dh, 1 ; Put DH=1, head
continueread:
jmp fullread ; Do it all again
endload: ; Changed name
mov dx,0x3F2 ; Turn off floppy motor
mov al,0x0C
out dx,al
ret
pmode:
;==========Into PMODE!==========
cli ; Turn off interrupts
mov eax,cr0 ; Get CR0 into EAX
or al,1 ; Make certain bit 0 = 1
mov cr0,eax ; Put EAX into CR0
;==========Load the General Descriptor Table==========
lgdt[GDTR] ; Load GDTR pointer
;==========Reinitialize all registers for jump into Kernel==========
mov ax,DATASEL ; Setup segments (changed to AX, segments are 16 bits)
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,0xfffc ; Just below 64kB linear
jmp CODESEL:switch
;[BITS 32]
use32
switch:
jmp CODESEL:0x100000 ; Jump to 1MB where to kernel was loaded
hlt
;==========DATA (GDT) AREA==========
GDTR:
GDTsize DW GDTEND-GDT-1
GDTbase DD GDT
GDT:
NULLSEL EQU $-GDT
DD 0x0
DD 0x0
CodeSelector:
DW 0xFFFF
DW 0x0
DB 0x0
DB 0x9A
DB 0xCF
DB 0x0
DataSelector:
DW 0xFFFF
DW 0x0
DB 0x0
DB 0x92
DB 0xCF
DB 0x0
GDTEND:
;==========AND THE BOOT SIGNATURE==========
TIMES 510-($-BootSector) DB 0
SIGNATURE DW 0xAA55
-smiddy