OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Dec 06, 2019 5:58 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: qemu differences between -fda and -hda(and a smal VGA issue)
PostPosted: Sun Jan 06, 2019 9:51 am 
Offline

Joined: Sun Jan 06, 2019 9:20 am
Posts: 4
Im quiet newt in kernels and bootloaders.
I recently wrote a basic bootloader and a kernel that should change colors in the VGA palette.
The kernel doesnt make any problems runs perfectly but It does not change the colors as expectet.
Since I was not able to find a mistake I tried to run the bootloader+kernel from a bootstick on my machine. I got a blackscreen and a blinking cursor.
So I decided to use a gui tool for writing the bootstick ("usb-creator-gtk"), I used it to write my img file to the stick and then tested it using qemu as the program asked me to do.
The bootloader was not able to load the kernel. (qemu-system-x86_64 -hda /dev/sdc)
But if I use qemu-system-x86_64 -fda /dev/sdc the kernel gets loaded and works (except the VGA palette).

How I load the kernel code :
Code:
load_kernel_dx_drive_sectors:
  xor ax, ax;set zero
  mov es, ax;ser es zero
  mov bx, 0x9000 ;(es:bx)
 
  push dx ;backup input data  (dl=BOOT_DRIVE, dh=SECTORS)
 
  mov ah, 0x02 ;13h : read from disk
  mov al, dh ; read dh sectors
  mov ch, 0x00 ; cylinder 0
  mov dh, 0x00 ; head 0
  mov cl, 0x02 ; start reading from the 2nd cylinder (skip boot sector)
 
  int 13h ; EXECUTE

Then it jumps to .error and the screen gets "purple"
Code:
  jc .error; error (carryflag not set) --> red screen 
  pop dx
  cmp dh, al ; al = sectors read --> if not as expected then : ERROR
  jne .error2
 
  push 0x0d;
  push 320*200
  call clearScreen_char_n
  add esp, 4
 
  ret
.error:
  push 0x0d;
  push 320*200
  call clearScreen_char_n
  add esp, 4
  ret

.error2:
  push 0x0f;
  push 320*200
  call clearScreen_char_n
  add esp, 4
  ret


The Way I compile:
Code:
nasm boot.asm -f bin -o boot.bin
nasm -f elf32 kernel.asm -o kasm.o
gcc -w -g -m32 -c -ffreestanding -o kernel.o kernel.c -lgcc
ld -melf_i386 -Tlinker.ld -nostdlib --nmagic -o kernel.elf kernel.o kasm.o
objcopy -O binary kernel.elf kernel.bin

dd if=/dev/zero of=disk.img bs=512 count=2880
dd if=boot.bin of=disk.img bs=512 conv=notrunc
dd if=kernel.bin of=disk.img bs=512 seek=1 conv=notrunc


My linker script :
Code:
OUTPUT_FORMAT(elf32-i386)
ENTRY(main)

SECTIONS
{
    . = 0x9000;
    .text : { *(.text) }
    .data : { *(.data) }
    .bss  : { *(.bss) *(COMMON) }
}


I think It does not matter but to be sure, how I change the palette:
Code:
void writeVGA_DAC_color(char index, char r, char g, char b){
  write_port(0x3C6, 0b11111111);
  write_port(0x3C8, index);
  write_port(0x3C9, r);
  write_port(0x3C9, g);
  write_port(0x3C9, b);
}


I hope someone can explain that behaviour to me/tell me what I do wrong.
Thanks in advance.


Top
 Profile  
 
 Post subject: Re: qemu differences between -fda and -hda(and a smal VGA is
PostPosted: Sun Jan 06, 2019 11:08 am 
Online
Member
Member
User avatar

Joined: Tue Mar 06, 2007 11:17 am
Posts: 1208
From Tutorial 2 of Denthor of Asphixia (TUT2.TXT):
http://planet-source-code.com/vb/script ... 1&lngWId=3

0x3C8 is the palette color index write port.
0x3C9 is the 3-byte RGB register for the current color index.

Code:
Procedure WritePalette(ColorNum: Byte; R,G,B: Byte);
  {
   It writes the values of Red, Green and Blue
   for a given color
  }
Begin
   Port[$3C8] := ColorNum;
   Port[$3C9] := R;
   Port[$3C9] := G;
   Port[$3C9] := B;
End;

_________________
http://190.53.102.175/api/doc/ (My OS compatible with DOS)

(udocproject@yahoo.com)
-----------------------------
IP for hosts file (all domains):
190.53.102.175 api.exe


Top
 Profile  
 
 Post subject: Re: qemu differences between -fda and -hda(and a smal VGA is
PostPosted: Sun Jan 06, 2019 12:46 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 498
Regarding the issue of booting from a USB stick (and not the palette). I assume you it gave you a blank screen and cursor on real hardware? If so, were you booting your USB using FDD (Floppy Disk Emulation). This is likely a setting in the BIOS. If it is FDD then the reason it may not have worked is because of not having a BIOS Parameter Block(BPB). You might want to see my Stackoverflow Answer to see if this might have been part of the problem. If you didn't properly initialize your segments to what you need (rather on relying on values set by the BIOS before transferring to your bootloader) that could cause problems as well.

Unfortunately it is hard to tell because you only show snippets of code, and not everything.


Top
 Profile  
 
 Post subject: Re: qemu differences between -fda and -hda(and a smal VGA is
PostPosted: Sun Jan 06, 2019 1:11 pm 
Offline

Joined: Sun Jan 06, 2019 9:20 am
Posts: 4
I found out what was wrong with my code. I used x00 as bootdrive which apears to only work for floppys (-fda), I changed to 0x80 for harddrives (-hda) and the bootstick booted perfectly (on real hardware too).
The only thing that remains is the palette which Im currently working on.


Last edited by FATTOMCAT on Sun Jan 06, 2019 2:17 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: qemu differences between -fda and -hda(and a smal VGA is
PostPosted: Sun Jan 06, 2019 2:14 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 498
You don't need to hard code the boot drive. When the BIOS transfers control to your bootloader it will set DL to the drive that was booted on. If you just use the value passed by the BIOS in DL then you can avoid hard coding a value like 0x00, 0x80, 0x81 etc.


Top
 Profile  
 
 Post subject: Re: qemu differences between -fda and -hda(and a smal VGA is
PostPosted: Sun Jan 06, 2019 2:18 pm 
Offline

Joined: Sun Jan 06, 2019 9:20 am
Posts: 4
Ok, I'll give it a try.
Thanks

I have tried it it works with qemu but not on my computer (just a black screen with blinking cursor).

One more edit :
It works now whit the "automatic" dl.
I didn't have a BPB.


Top
 Profile  
 
 Post subject: Re: qemu differences between -fda and -hda(and a smal VGA is
PostPosted: Sun Jan 06, 2019 3:34 pm 
Offline

Joined: Sun Jan 06, 2019 9:20 am
Posts: 4
To the Palette:

I followed the steps in the tutorial posted by "~" as closely as possible but my color does not change.

The stuff i produced :

Code:

extern void write_port(unsigned char port, unsigned char value);

void fill(int color){
  volatile unsigned char * video_ptr = (volatile unsigned char *) VIDEO_PTR;
  int counter =0;
 
  while(counter < 320*200){
      video_ptr[counter] = color;
      counter ++;
  } 
}

void writeVGA_DAC_color(unsigned char index, unsigned char r, unsigned char g, unsigned char b){
  write_port((unsigned char)0x3C6, 0b11111111); //init DAC mask
  write_port((unsigned char)0x3C8, index);
  write_port((unsigned char)0x3C9, r);
  write_port((unsigned char)0x3C9, g);
  write_port((unsigned char)0x3C9, b);
}

void drawHorizontalLine(int x, int y, int length, unsigned char color){
  volatile unsigned char * video_ptr = (volatile unsigned char *) VIDEO_PTR;
  int pos = 320*y + x;
  int counter = 0;
  while(counter < length){
    video_ptr[pos] = color;
    pos ++;
    counter ++;
  }
}

void drawVerticalLine(int x, int y, int length, unsigned char color){
  volatile unsigned char * video_ptr = (volatile unsigned char *) VIDEO_PTR;
 
  int pos = 320*y + x;
  int counter = 0;
 
  while(counter < length){
    video_ptr[pos] = color;
    pos += 320;
    counter ++;
  }
 
}



asm :

Code:
write_port:
        mov   edx, [esp + 4]    ; push argument 1 to edx
        mov   al, [esp + 4 + 4]  ; push argument 2 to al (lower output)
        out   dx, al  ; write al to port dx
        ret


The main function :
Code:
void main(){
 
  //unsigned char * result;
  //volatile unsigned char * video_ptr = (volatile unsigned char *) VIDEO_PTR;
 
  fill(0xf7);
  drawVerticalLine(30, 100, 50, 0x09);
  drawHorizontalLine(30, 100, 200, 0x09);
  writeVGA_DAC_color(0x09, 0b11111111, 0, 0);//doesn't work
  drawVerticalLine(30, 100, 50, 0x09);
  drawHorizontalLine(30, 100, 200, 0x09);
 
  return;
}


Top
 Profile  
 
 Post subject: Re: qemu differences between -fda and -hda(and a smal VGA is
PostPosted: Sun Jan 06, 2019 6:07 pm 
Online
Member
Member
User avatar

Joined: Tue Mar 06, 2007 11:17 am
Posts: 1208
Try to remove this line. This is the PEL Mask Register. It's supposed to be already initialized by the BIOS. You need to study carefully the video mode you intend to use (whether has planes or not, memory organization, start video address, whether it uses a pallete):

Code:
  write_port((unsigned char)0x3C6, 0b11111111); //init DAC mask




If it doesn't work, try to produce functions identical to the ones from Denthor's TUT2.TXT in addition to yours. Run it at least under DOSBox, extract the functions and try them. If not, something else happens with your video mode. They should work. The link I posted seems to have them in C, assembly and Pascal.

_________________
http://190.53.102.175/api/doc/ (My OS compatible with DOS)

(udocproject@yahoo.com)
-----------------------------
IP for hosts file (all domains):
190.53.102.175 api.exe


Top
 Profile  
 
 Post subject: qemu differences between -fda and -hda(and a smal VGA issue)
PostPosted: Mon Jan 07, 2019 8:41 am 
Online
Member
Member
User avatar

Joined: Tue Mar 06, 2007 11:17 am
Posts: 1208
Try the attached EXE/C demo file for a cleaner way to handle the standard 256-color VGA palette.

Code:
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

/*

Functions:
---------------------------------------------
void VGA_ModifyPalette256Color(
                               unsigned char Color0_255,
                               unsigned char *RGB
                              );

Modifies a single color in the VGA's
256-color palette, a color index from 0 to 255.
The function needs a char array with 3
elements to hold the RGB value.


---------------------------------------------
void VGA_BIOS_enter_mode13h(void)

Enter the VGA/MCGA BIOS graphics mode 13h 320x200x256-color.


---------------------------------------------
void VGA_BIOS_enter_mode03h(void)

Enter the MCGA BIOS text mode 03h 80x25x16-color.


---------------------------------------------
void VGA_palette256_test_320x200_pixel_screen()

Tests the BIOS mode 13h mode by increasing in 1
each pixel value for the 64000 visible bytes
(320*200) starting at physical address 0xA0000.


---------------------------------------------
unsigned char CMOS_read(unsigned char idx)

Reads a value from the CMOS memory.
The index can be between 0 to 255.
Find a CMOS map to know what data is located
at each CMOS position, for example at
http://www.bioscentral.com/misc/cmosmap.htm


---------------------------------------------
void VGA_test_random_palette256()

Tries to generate a random palette to demonstrate
changing random colors from it.


---------------------------------------------


*/





/*
Implementation


Write a byte value to port 0x3C8
to set the 256-color palette index
that we want to write.

Then write port 0x3C9 3 consecutive
times with 1 byte to set the RGB values.

Each palette value only uses 6 effective bits
(values 0 to 63). The combination of RGB
for the VGA results in a 18-bit color that
adjusts the screen from darkness to full
white for each color in the 256-color palette.

Port 0x3C8 -- PEL Addres Write Mode Register
Port 0x3C9 -- PEL Data Register

*/
void VGA_ModifyPalette256Color(
                unsigned char Color0_255,
                unsigned char *RGB
               )
{
outportb(0x3C8,Color0_255&0xFF);  //Write byte: Index color 0-255

outportb(0x3C9,RGB[0]&63);  //Write byte: Red
outportb(0x3C9,RGB[1]&63);  //Write byte: Green
outportb(0x3C9,RGB[2]&63);  //Write byte: Blue
}




/*
Implementation


mov ax,0x0013
int 10h

Call BIOS INT 10h service 00h to set
VGA/MCGA graphics mode 13h (320x200x256-color).


*/
void VGA_BIOS_enter_mode13h(void)
{
_AX = 0x0013;
geninterrupt(0x10);
}










/*
Implementation


mov ax,0x0003
int 10h

Call BIOS INT 10h service 00h to set
VGA/MCGA text mode 03h (80x25x16-color).


*/
void VGA_BIOS_enter_mode03h(void)
{
_AX = 0x0003;
geninterrupt(0x10);
}









//A single palette triplet:
///
  unsigned char _RGB[3];

//A generic pointer to the start
//of memory for a given VGA mode:
///
  unsigned char *vga;






/*
Implementation


Point, with a C pointer, to
physical address 0xA0000.

Now inside a loop (while 0)
we will traverse index values
0 to 64000 for the 320*200 screen.
Write the the test byte (char)
pixel color at address
(vga_start+while0_index). Increase the
test pixel color in 1. Increase
the while 0 index in 1. Here ends
the while 0 loop.


*/
void VGA_palette256_test_320x200_pixel_screen()
{
//This index x needs to be unsigned int or
//unsigned long, wideword, or uwide_t
//for compatibility with 16-bit compilers:
///
  unsigned int x=0;

char test_pixel_color=0;

//Write the whole screen increasing the
//pixel color:
///
  while(x<64000) //while 0 START
  {
   *(vga+x)=test_pixel_color;  //Write pixel
   test_pixel_color++;         //Increase pixel color index in 1 (0-255)
   x++;                        //Increase 320x200 screen position
  }              //while 0 END


}




/*
Implementation


Pass an 8-bit index value in a byte
argument to specify which CMOS memory
position we want to read.

Write the byte index value to port 0x70.

Read the byte value at that index address
from the CMOS from port 0x71.

Return the contents of the CMOS byte
at that position as an unsigned char.


*/
unsigned char CMOS_read(unsigned char idx)
{
unsigned char toRet=0;

outportb(0x70,idx);
toRet=inportb(0x71);


return toRet;
}




/*
Implementation


Work only with unsigned integers since
we want to have at least a range of 0 to 65535
even with 16-bit compilers.

Create a random value from the values
that change constantly in the CMOS
by constantly adding the values for
RTC seconds,
RTC minutes,
RTC hours,
RTC day of week,
RTC data day,
RTC date month,
RTC date year
(CMOS positions 0, 2, 4, 6, 7, 8, 9).
Read those values through a random-generating
function and add them all, and also add
them directly, also adding the
previous value in the CMOS "random" value
with += for the full expression.

Also generate a random pixel start
unsigned integer by adding the value of
a random-generating function and the CMOS
random value.

The while 0 loop index must start randomly
between 0 and 127 for added randomness.

Now, inside a loop (while 0), we will
generate the RGB triplet values as randomly
as possible, and then we will modify each
palette index from a random start to 255.

The R, G and B components will use the exact
same CMOS_rand expression, but we will duplicate
it so that each component, each time, can be
as random as possible, specially because the
random functions from Turbo C (at least 1.01)
aren't truly random. They seem to produce the same
random value always once the program is compiled,
so we must use the dynamic values from the CMOS
and long delaying for more randomness based on the
Real Time Clock (RTC).

For each component, RGB[0], RGB[1] and RGB[2],
think up on any expressions that result in highly
random values. After setting each of them, call
delay() or equivalent with a value between 10 and
30 milliseconds for making the CMOS randomness
have more effect.

Now write the color by calling our function to
modify the effective color of a single color index
of the 256-color VGA palette. For calling it,
employ the same randomizing expression for CMOS_rand,
duplicating it again, and limiting it to 0-255 by
ANDing with 0xFF to write random palette positions
instead of modifying it sequentially.

Increase the while 0 index, which goes from
a random start to 255. Here ends the while 0 loop.


*/
void VGA_test_random_palette256()
{
unsigned int x;
unsigned int rand_pixel_start;
unsigned int CMOS_rand;

  CMOS_rand+=CMOS_read(0)+CMOS_read(2)+CMOS_read(4)+CMOS_read(6)+CMOS_read(7)+CMOS_read(8)+CMOS_read(9)+random(CMOS_read(0))+random(CMOS_read(2))+random(CMOS_read(4))+random(CMOS_read(6))+random(CMOS_read(7))+random(CMOS_read(8))+random(CMOS_read(9));
  rand_pixel_start=rand()+CMOS_rand;
  x=(CMOS_rand)&0x7F;
  while(x<256) //while 0 START
  {
   //R
   CMOS_rand+=CMOS_read(0)+CMOS_read(2)+CMOS_read(4)+CMOS_read(6)+CMOS_read(7)+CMOS_read(8)+CMOS_read(9)+random(CMOS_read(0))+random(CMOS_read(2))+random(CMOS_read(4))+random(CMOS_read(6))+random(CMOS_read(7))+random(CMOS_read(8))+random(CMOS_read(9));
   _RGB[0]=CMOS_rand+rand_pixel_start&63;
   delay(10);

   //G
   CMOS_rand+=CMOS_read(0)+CMOS_read(2)+CMOS_read(4)+CMOS_read(6)+CMOS_read(7)+CMOS_read(8)+CMOS_read(9)+random(CMOS_read(0))+random(CMOS_read(2))+random(CMOS_read(4))+random(CMOS_read(6))+random(CMOS_read(7))+random(CMOS_read(8))+random(CMOS_read(9));
   _RGB[1]=CMOS_rand+rand()&63;
   delay(20);

   //B
   CMOS_rand+=CMOS_read(0)+CMOS_read(2)+CMOS_read(4)+CMOS_read(6)+CMOS_read(7)+CMOS_read(8)+CMOS_read(9)+random(CMOS_read(0))+random(CMOS_read(2))+random(CMOS_read(4))+random(CMOS_read(6))+random(CMOS_read(7))+random(CMOS_read(8))+random(CMOS_read(9));
   _RGB[2]=CMOS_rand+(rand_pixel_start>>1)&63;
   delay(30);


   //Write color triplet in the VGA
   CMOS_rand+=CMOS_read(0)+CMOS_read(2)+CMOS_read(4)+CMOS_read(6)+CMOS_read(7)+CMOS_read(8)+CMOS_read(9)+random(CMOS_read(0))+random(CMOS_read(2))+random(CMOS_read(4))+random(CMOS_read(6))+random(CMOS_read(7))+random(CMOS_read(8))+random(CMOS_read(9));
   VGA_ModifyPalette256Color((unsigned char)(x+CMOS_rand)&0xFF,_RGB);
   x++;
  }            //while 0 END

}





/*
Implementation


Set a VGA start pointer to physical address
0xA0000 to address bytes or chars.

Enter mode 13h with the BIOS.

Print a message telling the user to press
ENTER to watch a sequential screen write
demo for 320x200x256-color graphics mode.

After pressing ENTER, show the user another
message asking to press ENTER again to
watch a demostration of changing the VGA
256-color palette randomly. Show the demo
and wait for the user to press ENTER.

When the user presses ENTER, return to
80x25 text mode 03h with the BIOS.
Show a message saying that the demo has ended
and wait for the user to press ENTER one
last time to exit the program.


*/
int main(void)
{
//Point to the base of memory for
//graphics mode 13h, located at
//flat address 0xA0000:
///
  vga = MK_FP(0xA000, 0);


//Enter graphics mode 13h 320x200x256-color VGA/MCGA
//and display a message with the DOS C library
//from Turbo C:
///
  VGA_BIOS_enter_mode13h();
  printf("Press ENTER to test the default palette\n");
  getchar();
  VGA_palette256_test_320x200_pixel_screen();
  getchar();


//Change the palette randomly
//and test again the result:
///
  printf("Press ENTER to test a random palette\n");
  getchar();

  VGA_test_random_palette256();

  VGA_palette256_test_320x200_pixel_screen();
  getchar();




//Return to text mode 03h 80x25x16-color
//MCGA and display a message with the
//DOS C library from Turbo C:
///
  VGA_BIOS_enter_mode03h();
  printf("Ended\n");
  getchar();


return 0;
}













  //Se ve como si aumentaran en 1 cada pixel
  //en una paleta de 256 colores con suficiente
  //diferencia entre cada color de la paleta.

  //The graphic of the code looks like it increases
  //by 1 each pixel value in a 256-color palette
  //with enough difference between each palette
  //color.

  //El fuego se ve como... (al analizar el algoritmo
  //para ver cómo se va formando); un efecto de haz de luz
  //afilado pero desenfocado (como el de Expert Software) se ve como...



Attachments:
VGAPAL.zip [12.58 KiB]
Downloaded 6 times

_________________
http://190.53.102.175/api/doc/ (My OS compatible with DOS)

(udocproject@yahoo.com)
-----------------------------
IP for hosts file (all domains):
190.53.102.175 api.exe
Top
 Profile  
 
 Post subject: Re: qemu differences between -fda and -hda(and a smal VGA is
PostPosted: Mon Jan 07, 2019 9:57 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9287
Location: On the balcony, watching the Swedish Chef
Code:
  writeVGA_DAC_color(0x09, 0b11111111, 0, 0);//doesn't work
The DAC has 3x 6-bit registers. That's an 8-bit value.

_________________
"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  
 
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] and 16 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