diff -Nur qemu-cvs/Makefile qemu-dosemu/Makefile --- qemu-cvs/Makefile 2004-08-03 23:13:35.000000000 +0200 +++ qemu-dosemu/Makefile 2004-09-02 16:10:17.000000000 +0200 @@ -20,7 +20,7 @@ $(MAKE) -C $$d $@ || exit 1 ; \ done -qemu-img: qemu-img.c block.c block-cow.c block-qcow.c aes.c block-vmdk.c +qemu-img: qemu-img.c block.c block-cow.c block-dosemu.c block-qcow.c aes.c block-vmdk.c $(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS) dyngen$(EXESUF): dyngen.c diff -Nur qemu-cvs/Makefile.target qemu-dosemu/Makefile.target --- qemu-cvs/Makefile.target 2004-08-25 19:34:05.000000000 +0200 +++ qemu-dosemu/Makefile.target 2004-09-02 16:10:17.000000000 +0200 @@ -241,7 +241,7 @@ # must use static linking to avoid leaving stuff in virtual address space VL_OBJS=vl.o osdep.o block.o readline.o monitor.o pci.o console.o -VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o +VL_OBJS+=block-dosemu.o block-cow.o block-qcow.o aes.o block-vmdk.o ifeq ($(TARGET_ARCH), i386) # Hardware support diff -Nur qemu-cvs/block-dosemu.c qemu-dosemu/block-dosemu.c --- qemu-cvs/block-dosemu.c 1970-01-01 01:00:00.000000000 +0100 +++ qemu-dosemu/block-dosemu.c 2004-09-02 16:10:17.000000000 +0200 @@ -0,0 +1,197 @@ +/* + * Block driver for the DOSEMU format + * + * Copyright (c) 2004 Hampa Hug + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "vl.h" +#include "block_int.h" + +#include +#include +#include + +/**************************************************************/ +/* DOSEMU block driver */ + +typedef struct BDRVDosemuState { + FILE *fp; + uint32_t tracks; + uint32_t heads; + uint32_t sectors; + uint32_t offset; + uint64_t blocks; +} BDRVDosemuState; + + +static int dosemu_probe(const uint8_t *buf, int buf_size, const char *filename) +{ + if ((buf_size >= 7) && (memcmp(buf, "DOSEMU\x00", 7) == 0)) { + return 100; + } + + return 0; +} + +static int dosemu_open_fp(BlockDriverState *bs, FILE *fp) +{ + BDRVDosemuState *s = bs->opaque; + uint8_t buf[128]; + + s->fp = fp; + + if (fread(buf, 1, 128, fp) != 128) { + return 1; + } + + if (memcmp(buf, "DOSEMU\x00", 7) != 0) { + return 1; + } + + s->tracks = le32_to_cpupu ((void *) (buf + 15)); + s->heads = le32_to_cpupu ((void *) (buf + 7)); + s->sectors = le32_to_cpupu ((void *) (buf + 11)); + s->offset = le32_to_cpupu ((void *) (buf + 19)); + s->blocks = (uint64_t) s->tracks * s->heads * s->sectors; + + bs->total_sectors = s->blocks; + + bdrv_set_geometry_hint (bs, s->tracks, s->heads, s->sectors); + + return 0; +} + +static int dosemu_open(BlockDriverState *bs, const char *filename) +{ + FILE *fp; + + fp = fopen(filename, "r+b"); + + if (fp == NULL) { + fp = fopen(filename, "rb"); + } + + if (fp == NULL) { + return -1; + } + + if (dosemu_open_fp(bs, fp)) { + fclose (fp); + return -1; + } + + return 0; +} + +static int dosemu_read(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors) +{ + BDRVDosemuState *s = bs->opaque; + + if (fseeko(s->fp, s->offset + 512 * sector_num, SEEK_SET)) { + return -1; + } + + if (fread(buf, 512, nb_sectors, s->fp) != nb_sectors) { + return -1; + } + + return 0; +} + +static int dosemu_write(BlockDriverState *bs, int64_t sector_num, + const uint8_t *buf, int nb_sectors) +{ + BDRVDosemuState *s = bs->opaque; + long n; + + n = 512L * nb_sectors; + + if (fseeko(s->fp, s->offset + 512 * sector_num, SEEK_SET)) { + return -1; + } + + if (fwrite(buf, 512, nb_sectors, s->fp) != nb_sectors) { + return -1; + } + + fflush (s->fp); + + return 0; +} + +static int dosemu_close(BlockDriverState *bs) +{ + BDRVDosemuState *s = bs->opaque; + + fclose(s->fp); + + return 0; +} + +static int dosemu_create(const char *filename, int64_t total_size, + const char *backing_file, int flags) +{ + int ret; + uint32_t tracks, heads, sectors; + unsigned char buf[12]; + FILE *fp; + + if (flags || backing_file) { + return -ENOTSUP; + } + + /* should choose sectors and tracks based on total_size */ + sectors = 63; + heads = 128; + tracks = (total_size + (sectors * heads) / 2) / (sectors * heads); + + fp = fopen(filename, "wb"); + if (fp == NULL) { + return -EIO; + } + + memset (buf, 0, 128); + memcpy (buf, "DOSEMU\x00", 7); + + cpu_to_le32wu ((void *) (buf + 15), tracks); + cpu_to_le32wu ((void *) (buf + 7), heads); + cpu_to_le32wu ((void *) (buf + 11), sectors); + cpu_to_le32wu ((void *) (buf + 19), 128); + + ret = fwrite(buf, 1, 128, fp); + + fclose(fp); + + if (ret != 128) { + return -EIO; + } + + return 0; +} + + +BlockDriver bdrv_dosemu = { + "dosemu", + sizeof(BDRVDosemuState), + dosemu_probe, + dosemu_open, + dosemu_read, + dosemu_write, + dosemu_close, + dosemu_create, +}; diff -Nur qemu-cvs/block.c qemu-dosemu/block.c --- qemu-cvs/block.c 2004-08-03 23:14:09.000000000 +0200 +++ qemu-dosemu/block.c 2004-09-02 16:10:17.000000000 +0200 @@ -558,6 +558,7 @@ { BDRVRawState *s = bs->opaque; close(s->fd); + return 0; } static int raw_create(const char *filename, int64_t total_size, @@ -591,6 +592,7 @@ void bdrv_init(void) { bdrv_register(&bdrv_raw); + bdrv_register(&bdrv_dosemu); #ifndef _WIN32 bdrv_register(&bdrv_cow); #endif diff -Nur qemu-cvs/vl.h qemu-dosemu/vl.h --- qemu-cvs/vl.h 2004-08-24 23:24:45.000000000 +0200 +++ qemu-dosemu/vl.h 2004-09-02 16:10:17.000000000 +0200 @@ -351,6 +351,7 @@ typedef struct BlockDriver BlockDriver; extern BlockDriver bdrv_raw; +extern BlockDriver bdrv_dosemu; extern BlockDriver bdrv_cow; extern BlockDriver bdrv_qcow; extern BlockDriver bdrv_vmdk;