--- oldqemu/block-vvfat.c	2007-09-17 11:09:43.000000000 +0300
+++ newqemu/block-vvfat.c	2007-09-22 22:58:17.044333017 +0300
@@ -244,15 +244,11 @@ typedef struct bootsector_t {
 
 typedef struct partition_t {
     uint8_t attributes; /* 0x80 = bootable */
-    uint8_t start_head;
-    uint8_t start_sector;
-    uint8_t start_cylinder;
-    uint8_t fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xb = FAT32 */
-    uint8_t end_head;
-    uint8_t end_sector;
-    uint8_t end_cylinder;
+    uint8_t start_CHS[3];
+    uint8_t fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xe = FAT16_LBA, 0xb = FAT32, 0xc = FAT32_LBA */
+    uint8_t end_CHS[3];
     uint32_t start_sector_long;
-    uint32_t end_sector_long;
+    uint32_t length_sector_long;
 } __attribute__((packed)) partition_t;
 
 typedef struct mbr_t {
@@ -350,26 +346,52 @@ typedef struct BDRVVVFATState {
     int downcase_short_names;
 } BDRVVVFATState;
 
+static int convert_sector2CHS(BlockDriverState* bs, uint8_t * CHS, int spos){
+    int head,sector;
+    sector   = spos % (bs->secs);  spos/= bs->secs;
+    head     = spos % (bs->heads); spos/= bs->heads;
+    if(spos >= bs->cyls){
+        /* Windows/Dos is seid to take 1023/255/63 as nonrepresentable CHS */
+        CHS[0] = 0xFF;
+        CHS[1] = 0xFF;
+        CHS[2] = 0xFF;
+        return 1;
+    }
+    CHS[0] = (uint8_t)head;//head
+    CHS[1] = (uint8_t)( (sector+1) | ((spos>>8)<<6) ); //sector+hi(cylinder)
+    CHS[2] = (uint8_t)spos;//cylinder
+    return 0;
+}
 
 static void init_mbr(BDRVVVFATState* s)
 {
     /* TODO: if the files mbr.img and bootsect.img exist, use them */
     mbr_t* real_mbr=(mbr_t*)s->first_sectors;
     partition_t* partition=&(real_mbr->partition[0]);
+    int lba;
 
     memset(s->first_sectors,0,512);
 
+    /* Win NT Disk Signature */
+    real_mbr->ignored[0x1b8]='q';
+    real_mbr->ignored[0x1b9]='e';
+    real_mbr->ignored[0x1ba]='m';
+    real_mbr->ignored[0x1bb]='u';
+   
     partition->attributes=0x80; /* bootable */
-    partition->start_head=1;
-    partition->start_sector=1;
-    partition->start_cylinder=0;
+    
+    lba =convert_sector2CHS(s->bs, partition->start_CHS, s->first_sectors_number-1);
+    lba|=convert_sector2CHS(s->bs, partition->end_CHS, s->sector_count);
+
+    partition->start_sector_long =cpu_to_le32(s->first_sectors_number-1);
+    partition->length_sector_long=cpu_to_le32(s->sector_count - s->first_sectors_number+1);
+
     /* FAT12/FAT16/FAT32 */
-    partition->fs_type=(s->fat_type==12?0x1:s->fat_type==16?0x6:0xb);
-    partition->end_head=s->bs->heads-1;
-    partition->end_sector=0xff; /* end sector & upper 2 bits of cylinder */;
-    partition->end_cylinder=0xff; /* lower 8 bits of end cylinder */;
-    partition->start_sector_long=cpu_to_le32(s->bs->secs);
-    partition->end_sector_long=cpu_to_le32(s->sector_count);
+    if(lba)
+        /*LBA partitions are identified by start/ength_sector_long not by CHS*/
+        partition->fs_type=(s->fat_type==12?0x1:s->fat_type==16?0xe:0xc);
+    else
+        partition->fs_type=(s->fat_type==12?0x1:s->fat_type==16?0x6:0xb);
 
     real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
 }
@@ -973,10 +995,10 @@ DLOG(if (stderr == NULL) {
 
     s->fat_type=16;
     /* LATER TODO: if FAT32, adjust */
-    s->sector_count=0xec04f;
     s->sectors_per_cluster=0x10;
-    /* LATER TODO: this could be wrong for FAT32 */
-    bs->cyls=1023; bs->heads=15; bs->secs=63;
+    /* Keep this geometry for disk +512MB and use LBA model*/
+    bs->cyls=1024; bs->heads=16; bs->secs=63;
+
 
     s->current_cluster=0xffffffff;
 
@@ -991,11 +1013,6 @@ DLOG(if (stderr == NULL) {
     if (!strstart(dirname, "fat:", NULL))
 	return -1;
 
-    if (strstr(dirname, ":rw:")) {
-	if (enable_write_target(s))
-	    return -1;
-	bs->read_only = 0;
-    }
 
     if (strstr(dirname, ":floppy:")) {
 	floppy = 1;
@@ -1005,6 +1022,8 @@ DLOG(if (stderr == NULL) {
 	bs->cyls = 80; bs->heads = 2; bs->secs = 36;
     }
 
+    s->sector_count=bs->cyls*bs->heads*bs->secs;
+
     if (strstr(dirname, ":32:")) {
 	fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n");
 	s->fat_type = 32;
@@ -1015,6 +1034,12 @@ DLOG(if (stderr == NULL) {
 	s->sector_count=2880;
     }
 
+    if (strstr(dirname, ":rw:")) {
+	if (enable_write_target(s))
+	    return -1;
+	bs->read_only = 0;
+    }
+
     i = strrchr(dirname, ':') - dirname;
     assert(i >= 3);
     if (dirname[i-2] == ':' && isalpha(dirname[i-1]))
@@ -1024,11 +1049,12 @@ DLOG(if (stderr == NULL) {
 	dirname += i+1;
 
     bs->total_sectors=bs->cyls*bs->heads*bs->secs;
-    if (s->sector_count > bs->total_sectors)
-	s->sector_count = bs->total_sectors;
+
     if(init_directories(s, dirname))
 	return -1;
 
+    s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;
+
     if(s->first_sectors_number==0x40)
 	init_mbr(s);
 
