From arnej@math.ntnu.no  Thu Feb 19 00:20:18 1998
Received: from romberg.math.ntnu.no (153@romberg.math.ntnu.no [129.241.15.150])
          by hub.freebsd.org (8.8.8/8.8.8) with SMTP id AAA27808
          for <FreeBSD-gnats-submit@freebsd.org>; Thu, 19 Feb 1998 00:20:10 -0800 (PST)
          (envelope-from arnej@math.ntnu.no)
Received: (qmail 7649 invoked from network); 19 Feb 1998 08:20:07 -0000
Received: from cauchy.math.ntnu.no (129.241.15.128)
  by romberg.math.ntnu.no with SMTP; 19 Feb 1998 08:20:07 -0000
Received: (from arnej@localhost)
          by cauchy.math.ntnu.no (8.8.7/8.8.4)
	  id JAA05073; Thu, 19 Feb 1998 09:20:06 +0100 (CET)
Message-Id: <199802190820.JAA05073@cauchy.math.ntnu.no>
Date: Thu, 19 Feb 1998 09:20:06 +0100 (CET)
From: arnej@math.ntnu.no
Reply-To: arnej@math.ntnu.no
To: FreeBSD-gnats-submit@freebsd.org
Subject: pcemu harddisk-access fixes
X-Send-Pr-Version: 3.2

>Number:         5788
>Category:       ports
>Synopsis:       pcemu harddisk-access fixes
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    joerg
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Feb 19 00:30:06 PST 1998
>Closed-Date:    Mon Feb 21 23:41:28 MET 2000
>Last-Modified:  Mon Feb 21 23:43:21 MET 2000
>Originator:     Arne Henrik Juul
>Release:        FreeBSD 2.2-STABLE i386
>Organization:
Norwegian University of Technology and Science
>Environment:
	Anything PC with pcemu, I guess.
>Description:

	I found myself with a need for something that could run
	DOS fdisk, format, sys, and so on directly onto a harddisk,
	preferrably without going to the machine and putting in the
	DOS floppies.  After looking around for PC emulators pcemu
	looked promising, and I enabled some of the code that was
	commented out for harddisk access, debugged a bit, added
	some missing interrupt functions (that didn't actually
	turn out to be the source of the problems I had :-) and
	so on.  Now I can boot off the original DOS 6.22 floppy#1
	and run fdisk and format :-)

        This still needs work so you can e.g. add harddisks
	from your .pcemurc file, but I thought I would send in the
	patches I have and ask that they be integrated and/or sent
	on to any pcemu maintainers (if such exists).

	I've split up the patches to make it clearer what they do:
	* patch-b1-cpule
		I got tired of the compiler warnings on LITTLE_ENDIAN
		and just changed it to CPU_LITTLE_ENDIAN for now.
	* patch-b2-panic
		When I enabled emulator debugging it would halt
		whenever it hit a missing interrupt emulation. This
		was a bit too much, since there are many INT functions
		that it is completely acceptable to ignore, so I changed
		those DEBUGs to PANICs.
	* patch-c1-h
		Some of the debug printf()s printed numbers in hex, some
		in decimal, and some in hex without any prefix or suffix
		to indicate so.  After reading the doc for function 18
		(decimal) and then finding I really needed 0x18 instead
		I changed all the hex formats to use a trailing h
		suffix (instead of 0x%02X or just %02X I used %02Xh).
		0x prefix would be fine as well, of course.
	* patch-c2-rom8x16
		"Added" one of the interrupts that can probably be
		ignored.
	* patch-c3-hdemul
		The actual harddisk support.  You still need to
		change the disk table to look like you want and increase
		NUMHDISKS, but that should be it.  The only real bugs
		in the old code was a couple of << 8 that should have
		been << 2, and one place (in "Get disk params") where
		it had been forgotten that the bios numbers sectors from 1.
		Some of the code I thought was needed turned out to
		be unnecessary (at least for my purposes) so have been
		left unimplemented or half-implemented, like "Set media type"
		which currently checks its parameters for sanity, then
		always returns "function not available" anyway.

	Any comments are welcome.  I don't know much about PC's, so
	anything added here is by the help of Ralf Brown's interrupt list,
	and any mistakes are very probably mine :-)

>How-To-Repeat:

	Please don't repeat :-)

>Fix:
	Here is the set of patches I developed as a shar file.
	Please integrate it if you like it and send it on to anyone who
	wants to maintain pcemu.

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	patch-b1-cpule
#	patch-b2-panic
#	patch-c1-h
#	patch-c2-rom8x16
#	patch-c3-hdemul
#
echo x - patch-b1-cpule
sed 's/^X//' >patch-b1-cpule << 'END-of-patch-b1-cpule'
Xdiff -ru Makefile.orig Makefile
X--- Makefile.orig	Wed Feb 18 10:51:27 1998
X+++ Makefile	Wed Feb 18 10:50:46 1998
X@@ -18,7 +18,7 @@
X # -DDEBUGGER         compiles in the debugger
X # -DKBUK             if you have a UK style 102 key keyboard
X-# -DBIG_ENDIAN       if your computer is big-endian (Sparc, 68000 etc)
X-# -DLITTLE_ENDIAN    if your computer is little-endian (80x86 etc)
X+# -DCPU_BIG_ENDIAN       if your computer is big-endian (Sparc, 68000 etc)
X+# -DCPU_LITTLE_ENDIAN    if your computer is little-endian (80x86 etc)
X # -DALIGNED_ACCESS   if your computer requires words to be on even boundaries
X # -DBIGCASE          If your compiler/computer can handle 256 case switches
X #
X@@ -53,7 +53,7 @@
X 
X CC      = gcc
X #OPTIONS = -DBOOT720 -DBIG_ENDIAN -DALIGNED_ACCESS -DBIGCASE -DINLINE_FUNCTIONS
X-OPTIONS = -DBOOT720 -DLITTLE_ENDIAN -DBIGCASE -DINLINE_FUNCTIONS \
X+OPTIONS = -DBOOT720 -DCPU_LITTLE_ENDIAN -DBIGCASE -DINLINE_FUNCTIONS \
X 	-DBOOTFILE=\"${LOCALPREFIX}/lib/pcemu/DriveA\"
X #XROOT   = /usr/local/X11R5
X XROOT   = /usr/X11R6
Xdiff -ru cpu.h.orig cpu.h
X--- cpu.h.orig	Wed Jun 22 16:24:50 1994
X+++ cpu.h	Wed Feb 18 10:50:46 1998
X@@ -113,13 +113,13 @@
X     format and back again. Obviously there is nothing to do for little-endian
X     machines... */
X 
X-#if defined(LITTLE_ENDIAN)
X+#if defined(CPU_LITTLE_ENDIAN)
X #   define ChangeE(x) (WORD)(x)
X #else
X #   define ChangeE(x) (WORD)(((x) << 8) | ((BYTE)((x) >> 8)))
X #endif
X 
X-#if defined(LITTLE_ENDIAN) && !defined(ALIGNED_ACCESS)
X+#if defined(CPU_LITTLE_ENDIAN) && !defined(ALIGNED_ACCESS)
X #   define ReadWord(x) (*(x))
X #   define WriteWord(x,y) (*(x) = (y))
X #   define CopyWord(x,y) (*x = *y)
END-of-patch-b1-cpule
echo x - patch-b2-panic
sed 's/^X//' >patch-b2-panic << 'END-of-patch-b2-panic'
Xdiff -ru orig.Makefile ./Makefile
X--- orig.Makefile	Wed Feb 18 10:50:46 1998
X+++ ./Makefile	Wed Feb 18 10:56:07 1998
X@@ -16,6 +16,7 @@
X # -DINLINE_FUNCTIONS if your compiler support inline functions (most do)
X # -DDEBUG            prints lots of debugging messages.
X # -DDEBUGGER         compiles in the debugger
X+# -DPANIC            halt emulator when you hit an unimplemented interrupt
X # -DKBUK             if you have a UK style 102 key keyboard
X # -DBIG_ENDIAN       if your computer is big-endian (Sparc, 68000 etc)
X # -DCPU_LITTLE_ENDIAN    if your computer is little-endian (80x86 etc)
Xdiff -ru orig.bios.c ./bios.c
X--- orig.bios.c	Fri Jun 24 13:39:47 1994
X+++ ./bios.c	Wed Feb 18 10:56:07 1998
X@@ -657,7 +657,7 @@
X         break;
X     default:
X         printf("unimplement INT 15h function %02X\n",*bregs[AH]);
X-#ifdef DEBUG
X+#ifdef PANIC
X         loc();
X         exit_emu();
X #else
X@@ -790,7 +790,7 @@
X         break;
X     default:
X         printf("unimplemented INT 1Ah function %02X\n", *bregs[AH]);
X-#ifdef DEBUG
X+#ifdef PANIC
X         loc();
X         exit_emu();
X #endif
X@@ -991,7 +991,7 @@
X         break;
X     default:
X         printf("Unimplemented INT 13h function %02X\n",*bregs[AH]);
X-#ifdef DEBUG
X+#ifdef PANIC
X         loc();
X         exit_emu();
X #endif
Xdiff -ru orig.vga.c ./vga.c
X--- orig.vga.c	Wed Jun 22 16:24:51 1994
X+++ ./vga.c	Wed Feb 18 10:56:07 1998
X@@ -560,7 +560,7 @@
X             break;
X         default:
X             printf("Unimplemented int 0x10 function 0x11 sub-function %02X\n",*bregs[AL]);
X-#ifdef DEBUG
X+#if PANIC
X             loc();
X             exit_emu();
X #endif
X@@ -584,7 +584,7 @@
X             break;
X         default:
X             printf("Unimplemented int 10 function 0x12 sub-function 0x%02X\n",*bregs[BL]);
X-#ifdef DEBUG
X+#ifdef PANIC
X             loc();
X             exit_emu();
X #endif
X@@ -615,7 +615,7 @@
X     default:
X         printf("Unimplemented int 10 function: %02X. AL = %02X  BL = %02X\n",
X                *bregs[AH], *bregs[AL], *bregs[BL]);
X-#ifdef DEBUG
X+#ifdef PANIC
X         loc();
X         exit_emu();
X #endif
END-of-patch-b2-panic
echo x - patch-c1-h
sed 's/^X//' >patch-c1-h << 'END-of-patch-c1-h'
Xdiff -ru ../work/pcemu1.01alpha/bios.c ./bios.c
X--- ../work/pcemu1.01alpha/bios.c	Wed Feb 18 11:09:11 1998
X+++ ./bios.c	Wed Feb 18 11:04:52 1998
X@@ -204,7 +204,7 @@
X 
X static void int_serial(void)
X {
X-    D(printf("In serial. Function = 0x%02X\n", *bregs[AH]););
X+    D(printf("In serial. Function = %02Xh\n", *bregs[AH]););
X 
X     CalcAll();
X     switch(*bregs[AH])
X@@ -219,7 +219,7 @@
X 
X static void int_printer(void)
X {
X-    D(printf("In printer. Function = 0x%02X\n", *bregs[AH]););
X+    D(printf("In printer. Function = %02Xh\n", *bregs[AH]););
X 
X     CalcAll();
X     switch(*bregs[AH])
X@@ -366,7 +366,7 @@
X     }
X     else
X     {
X-        D(printf("Writing ascii %02X scan %02X\n",ascii,scan););
X+        D(printf("Writing ascii %02Xh scan %02Xh\n",ascii,scan););
X         PutMemB(data_segment, tmp, ascii);
X         PutMemB(data_segment, tmp+1, scan);
X         SetCurKeyBufEnd(cend);
X@@ -385,7 +385,7 @@
X 
X     *bregs[AH] = 0;
X 
X-    D(printf("Read: %02X\n", code););
X+    D(printf("Read: %02Xh\n", code););
X     state = code & 0x80;
X     
X     if ((code & 0xe0) == 0xe0)
X@@ -487,7 +487,7 @@
X 
X             raw_to_BIOS(code, e0_code, &ascii, &scan);
X 
X-            D(printf("%02X/%02X\n", ascii, scan););
X+            D(printf("%02Xh/%02Xh\n", ascii, scan););
X             if (ascii != 0 || scan != 0)
X             {
X                 if (!(KB_1 & ALT) && ascii == 0 && e0_code)
X@@ -539,7 +539,7 @@
X             
X             SetCurKeyBufStart(cstart);
X             
X-            D(printf("Cleared key %02X\n", *bregs[AL]););
X+            D(printf("Cleared key %02Xh\n", *bregs[AL]););
X 
X             *bregs[CL] = 1;
X             break;
X@@ -567,7 +567,7 @@
X                         *bregs[AL] = 0x00;
X             
X             ZF = 0;
X-            D(printf("Returning key %02X from INT 16 1/11\n", *bregs[AL]););
X+            D(printf("Returning key %02Xh from INT 16 1/11\n", *bregs[AL]););
X         }
X 
X         break;
X@@ -615,7 +615,7 @@
X                       (!(!(KB_2 & SYSREQ)) << 7));
X         break;
X     default:
X-        D(printf("Warning: unimplemented INT 16 function %02X\n",func););
X+        D(printf("Warning: unimplemented INT 16 function %02Xh\n",func););
X         CF = 1;
X         break;
X     }
X@@ -624,7 +624,7 @@
X 
X static void int_extended(void)
X {
X-    D(printf("In INT 0x15. Function = 0x%02X\n", *bregs[AH]););
X+    D(printf("In INT 0x15. Function = %02Xh\n", *bregs[AH]););
X 
X     CalcAll();
X     CF = 1;
X@@ -635,8 +635,10 @@
X     case 0x85:
X         CF = 0;
X         break;
X-    case 0x10:
X     case 0x41:
X+        *bregs[AH] = 0x86;
X+        break;
X+    case 0x10:
X     case 0x64:
X     case 0xc0:
X     case 0xc1:
X@@ -656,7 +658,7 @@
X         *bregs[AH] = 1;
X         break;
X     default:
X-        printf("unimplement INT 15h function %02X\n",*bregs[AH]);
X+        printf("unimplemented INT 15h function %02Xh\n",*bregs[AH]);
X #ifdef PANIC
X         loc();
X         exit_emu();
X@@ -721,7 +723,7 @@
X     time_t curtime;
X     struct tm *local;
X 
X-    D(printf("In time. Function = 0x%02X\n", *bregs[AH]););
X+    D(printf("In time. Function = %02Xh\n", *bregs[AH]););
X 
X     CalcAll();
X     switch(*bregs[AH])
X@@ -737,7 +739,7 @@
X 
X         CF = 0;
X 
X-/*        D(printf("Returning %02X%02X%02X%02X\n", *bregs[CL], *bregs[CH],
X+/*        D(printf("Returning %02X%02X%02X%02Xh\n", *bregs[CL], *bregs[CH],
X                  *bregs[DH], *bregs[DL]);); */
X         break;
X     case 1:     /* Set ticks */
X@@ -789,7 +791,7 @@
X         CF = 1;
X         break;
X     default:
X-        printf("unimplemented INT 1Ah function %02X\n", *bregs[AH]);
X+        printf("unimplemented INT 1Ah function %02Xh\n", *bregs[AH]);
X #ifdef PANIC
X         loc();
X         exit_emu();
X@@ -843,7 +845,7 @@
X     switch(*bregs[AH])
X     {
X     case 0:
X-        D(printf("Initialise disk 0x%02X\n",*bregs[DL]););
X+        D(printf("Initialize disk %02Xh\n",*bregs[DL]););
X         CF = 0;
X         break;
X     case 1:  /* Get last error */
X@@ -890,10 +892,10 @@
X             break;
X         }
X         head = *bregs[DH];
X-        cylinder = *bregs[CH] + ((*bregs[CL] & 0xc0) << 8);
X+        cylinder = *bregs[CH] + ((*bregs[CL] & 0xc0) << 2);
X         sector = (*bregs[CL] & 0x3f) -1;
X         buffer = &c_es[ChangeE(wregs[BX])];
X-        D(printf("DISK 0x%02X (%s) read [h%d,s%d,t%d](%d)->%04X:%04X\n",
X+        D(printf("DISK %02Xh (%s) read [h%d,s%d,t%d](%d)->%04X:%04X\n",
X                  *bregs[DL], disk->name, head, sector, cylinder, *bregs[AL],
X                  sregs[ES], ChangeE(wregs[BX])););
X         if (disk_seek(disk, cylinder, head, sector))
X@@ -912,7 +914,7 @@
X         CF = 0;
X         break;
X     case 4: /* Test disk */
X-        D(printf("Testing disk 0x%02X\n",*bregs[DL]););
X+        D(printf("Testing disk %02Xh\n",*bregs[DL]););
X         disk = get_disk_tab(*bregs[DL]);
X         if (!disk)
X         {
X@@ -932,7 +934,7 @@
X         CF = 0;
X         break;
X     case 8: /* Get disk params */
X-        D(printf("Get disk params 0x%02X\n",*bregs[DL]););
X+        D(printf("Get disk params %02Xh\n",*bregs[DL]););
X         disk = get_disk_tab(*bregs[DL]);
X         if (disk)
X         {
X@@ -966,7 +968,7 @@
X         }
X         break;
X     case 0x15:  /* Get disk type */
X-        D(printf("Get disk type 0x%02X\n",*bregs[DL]););
X+        D(printf("Get disk type %02Xh\n",*bregs[DL]););
X         disk = get_disk_tab(*bregs[DL]);
X         if (disk)
X         {
X@@ -990,7 +992,7 @@
X         }
X         break;
X     default:
X-        printf("Unimplemented INT 13h function %02X\n",*bregs[AH]);
X+        printf("Unimplemented INT 13h function %02Xh\n",*bregs[AH]);
X #ifdef PANIC
X         loc();
X         exit_emu();
X@@ -1070,7 +1072,7 @@
X {
X     unsigned tmp,tmp2;
X 
X-    D(printf("In INT 0xe8 AH = 0x%02X  AL = 0x%02X\n",*bregs[AH],*bregs[AL]););
X+    D(printf("In INT 0xe8 AH = %02Xh  AL = %02Xh\n",*bregs[AH],*bregs[AL]););
X 
X     CalcAll();
X     switch(*bregs[AH])
Xdiff -ru ../work/pcemu1.01alpha/cpu.c ./cpu.c
X--- ../work/pcemu1.01alpha/cpu.c	Wed Feb 18 11:09:10 1998
X+++ ./cpu.c	Wed Feb 18 11:04:52 1998
X@@ -537,7 +537,7 @@
X #ifdef DEBUGGER
X     call_debugger(D_INT);
X #endif
X-    D2(printf("Interrupt 0x%02X\n", int_pending););
X+    D2(printf("Interrupt %02Xh\n", int_pending););
X     interrupt(int_pending);
X     int_pending = 0;
X 
X@@ -4163,7 +4163,7 @@
X 
X static INLINE2 void i_notdone(void)
X {
X-    fprintf(stderr,"Error: Unimplemented opcode %02X at cs:ip = %04X:%04X\n",
X+    fprintf(stderr,"Error: Unimplemented opcode %02Xh at cs:ip = %04X:%04X\n",
X 		    c_cs[ip-1],sregs[CS],ip-1);
X /*    exit(1); */
X }
Xdiff -ru ../work/pcemu1.01alpha/vga.c ./vga.c
X--- ../work/pcemu1.01alpha/vga.c	Wed Feb 18 11:09:11 1998
X+++ ./vga.c	Wed Feb 18 11:04:52 1998
X@@ -559,7 +559,7 @@
X             }
X             break;
X         default:
X-            printf("Unimplemented int 0x10 function 0x11 sub-function %02X\n",*bregs[AL]);
X+            printf("Unimplemented int 0x10 function 0x11 sub-function %02Xh\n",*bregs[AL]);
X #if PANIC
X             loc();
X             exit_emu();
X@@ -583,7 +583,7 @@
X             *bregs[AL] = 0x12;
X             break;
X         default:
X-            printf("Unimplemented int 10 function 0x12 sub-function 0x%02X\n",*bregs[BL]);
X+            printf("Unimplemented int 10 function 0x12 sub-function %02Xh\n",*bregs[BL]);
X #ifdef PANIC
X             loc();
X             exit_emu();
Xdiff -ru ../work/pcemu1.01alpha/xstuff.c ./xstuff.c
X--- ../work/pcemu1.01alpha/xstuff.c	Wed Feb 18 11:09:10 1998
X+++ ./xstuff.c	Wed Feb 18 11:04:52 1998
X@@ -523,7 +523,7 @@
X 
X             if (key == XK_Pause)
X             {
X-                D(printf("Pause pressed. State = %02X\n", event.xkey.state););
X+                D(printf("Pause pressed. State = %02Xh\n", event.xkey.state););
X                 if (event.xkey.state & ControlMask)
X                     scan = 0xc6e046e0;
X                 else
X@@ -531,7 +531,7 @@
X             }                   /* XK_F22 is sun type 4 PrtScr */
X             else if (key == XK_Print || key == XK_F22)
X             {
X-                D(printf("Print pressed. State = %02X\n", event.xkey.state););
X+                D(printf("Print pressed. State = %02Xh\n", event.xkey.state););
X                 if (event.xkey.state & Mod1Mask)
X                     scan = 0x54;
X                 else
END-of-patch-c1-h
echo x - patch-c2-rom8x16
sed 's/^X//' >patch-c2-rom8x16 << 'END-of-patch-c2-rom8x16'
Xdiff -ru orig.vga.c vga.c
X--- orig.vga.c	Wed Feb 18 11:11:30 1998
X+++ vga.c	Mon Feb 16 18:08:24 1998
X@@ -558,6 +558,15 @@
X                 wregs[BP] = ChangeE(0);
X             }
X             break;
X+	case 0x14:	/* Load rom 8x16 font */
X+	    if (height != 25) {
X+		height = 25;
X+		SetHeight(height);
X+		SetSize((width+1) * (height+1) * 2);
X+		new_screen(width+1, height+1, screen_mem);
X+		clearscr(0,0,width, height, 0x07);
X+	    }
X+            break;
X         default:
X             printf("Unimplemented int 0x10 function 0x11 sub-function %02Xh\n",*bregs[AL]);
X #if PANIC
END-of-patch-c2-rom8x16
echo x - patch-c3-hdemul
sed 's/^X//' >patch-c3-hdemul << 'END-of-patch-c3-hdemul'
Xdiff -ru orig.bios.c bios.c
X--- orig.bios.c	Wed Feb 18 11:11:30 1998
X+++ bios.c	Wed Feb 18 11:14:45 1998
X@@ -109,6 +109,12 @@
X { "/dev/fd0", 18, 80, 2 }
X };
X 
X+DiskTab hdisk[MAXHDISKS] =
X+{
X+{ "/dev/wd0", 63, 407, 64 },
X+{ "/some/file", 32, 120, 64 },
X+};
X+
X int bootdisk = 0x0;
X static unsigned pos = INT_ROUTINE_START;
X 
X@@ -803,13 +809,13 @@
X 
X static DiskTab *get_disk_tab(int num)
X {
X-    if (num < NUMFDISKS)
X+    if (num >= 0    && num < NUMFDISKS)
X         return &fdisk[num];
X-    
X+    if (num >= 0x80 && num < 0x80 + NUMHDISKS)
X+	return &hdisk[num&0x7f];
X     return NULL;
X }
X 
X-
X static int disk_seek(DiskTab *disk, int cylinder, int head, int sector)
X {
X     unsigned pos;
X@@ -817,6 +823,9 @@
X     if (head > disk->heads || cylinder > disk->cylinders ||
X         sector > disk->sectors)
X     {
X+        D(printf("error h%d>%d or c%d>%d or s%d>%d\n",*bregs[DL],
X+		head, disk->heads, cylinder, disk->cylinders,
X+		sector, disk->sectors););
X         CF = 1;
X         *bregs[AH] = diskerror = 0x4;  /* Sector not found */
X         return -1;
X@@ -853,7 +862,8 @@
X         *bregs[AH] = 0;
X         *bregs[AL] = diskerror;
X         break;
X-    case 2:  /* Write sector */
X+    case 2:  /* Read sector */
X+        D(printf("Read sector drive %02Xh\n", *bregs[DL]););
X         disk = get_disk_tab(*bregs[DL]);
X         if (!disk)
X         {
X@@ -865,7 +875,7 @@
X         cylinder = *bregs[CH] + ((*bregs[CL] & 0xc0) << 2);
X         sector = (*bregs[CL] & 0x3f) -1;
X         buffer = &c_es[ChangeE(wregs[BX])];
X-        D(printf("DISK 0x%02X (%s) read [h%d,s%d,t%d](%d)->%04X:%04X\n",
X+        D(printf("DISK %02Xh (%s) read [h%d,s%d,c%d](%d)->%04X:%04X\n",
X                  *bregs[DL], disk->name, head, sector, cylinder, *bregs[AL],
X                  sregs[ES], ChangeE(wregs[BX])););
X         if (disk_seek(disk, cylinder, head, sector))
X@@ -884,6 +894,7 @@
X         CF = 0;
X         break;
X     case 3:  /* Write sector */
X+        D(printf("write sector drive %02Xh\n", *bregs[DL]););
X         disk = get_disk_tab(*bregs[DL]);
X         if (!disk)
X         {
X@@ -895,7 +906,7 @@
X         cylinder = *bregs[CH] + ((*bregs[CL] & 0xc0) << 2);
X         sector = (*bregs[CL] & 0x3f) -1;
X         buffer = &c_es[ChangeE(wregs[BX])];
X-        D(printf("DISK %02Xh (%s) read [h%d,s%d,t%d](%d)->%04X:%04X\n",
X+        D(printf("DISK %02Xh (%s) read [h%d,s%d,c%d](%d)->%04X:%04X\n",
X                  *bregs[DL], disk->name, head, sector, cylinder, *bregs[AL],
X                  sregs[ES], ChangeE(wregs[BX])););
X         if (disk_seek(disk, cylinder, head, sector))
X@@ -923,8 +934,9 @@
X             break;
X         }
X         head = *bregs[DH];
X-        cylinder = *bregs[CH] + ((*bregs[CL] & 0xc0) << 8);
X+        cylinder = *bregs[CH] + ((*bregs[CL] & 0xc0) << 2);
X         sector = (*bregs[CL] & 0x3f) -1;
X+        D(printf("h%d c%d s%d\n",head, cylinder, sector););
X         buffer = &c_es[ChangeE(wregs[BX])];
X         if (disk_seek(disk, cylinder, head, sector))
X             break;
X@@ -949,12 +961,15 @@
X             case 18:
X                 *bregs[BL] = 4;
X                 break;
X+	    default:
X+                *bregs[BL] = 0;
X             }
X 
X             *bregs[CH] = (disk->cylinders - 1) & 0xff;
X-            *bregs[CL] = (disk->sectors - 1) | (((disk->cylinders - 1)
X+            *bregs[CL] = disk->sectors | (((disk->cylinders - 1)
X                                                  & 0x300) >> 2);
X-            *bregs[DH] = disk->heads -1;
X+            *bregs[DH] = (disk->heads -1) | (((disk->cylinders - 1)
X+					     & 0xc00)>> 4);
X             *bregs[DL] = *bregs[DL]  < 0x80 ? NUMFDISKS : NUMHDISKS;
X             *bregs[AL] = 0;
X             CF = 0;
X@@ -966,6 +981,19 @@
X             wregs[DX] = 0;
X             wregs[CX] = 0;
X         }
X+        D(printf("Ret CH=%02Xh, CL=%02Xh, DH=%02Xh, DL=%02Xh\n",
X+		*bregs[CH], *bregs[CL], *bregs[DH], *bregs[DL]););
X+        break;
X+    case 0x12:
X+        D(printf("Disk controller ram diag\n"););
X+        disk = get_disk_tab(*bregs[DL]);
X+	if (disk) {
X+            CF = 0;
X+            *bregs[AH] = diskerror = 0;
X+        } else {
X+            CF = 1;
X+            *bregs[AH] = diskerror = 0x20;
X+	}
X         break;
X     case 0x15:  /* Get disk type */
X         D(printf("Get disk type %02Xh\n",*bregs[DL]););
X@@ -991,6 +1019,38 @@
X             *bregs[AH] = 0;
X         }
X         break;
X+    case 0x18:
X+	D(printf("Set media type for format drive %02Xh\n", *bregs[DL]););
X+	D(printf("sectors %d\n", (*bregs[CL] & 0x3f)));
X+	D(printf("cylinders %d+%d\n",*bregs[CH], ((*bregs[CL] & 0xc0) << 2)));
X+
X+        disk = get_disk_tab(*bregs[DL]);
X+	if (disk) {
X+	    if (disk->sectors - 1 != (*bregs[CL] & 0x3f)) {
X+        	printf("INT 13h/18h: sectors %d != %d\n",
X+			disk->sectors, (*bregs[CL] & 0x3f));
X+		CF = 1;
X+		*bregs[AH] = diskerror = 0x0c;
X+	    }
X+	    if (disk->cylinders - 1
X+			!= (*bregs[CH] | ((*bregs[CL] & 0xc0) << 2))) {
X+        	printf("INT 13h/18h: cylinders %d != %d\n",
X+			disk->cylinders,
X+			(*bregs[CH] | ((*bregs[CL] & 0xc0) << 2)));
X+		CF = 1;
X+		*bregs[AH] = diskerror = 0x0c;
X+	    }
X+	    /* make 11-byte param table at F000h:E401h ? point ES:DI at it? */
X+            *bregs[AH] = diskerror = 0;
X+            CF = 0;
X+        } else {
X+            CF = 1;
X+            *bregs[AH] = diskerror = 0x80;
X+	}
X+        CF = 1;
X+        *bregs[AH] = diskerror = 0x01;
X+        break;
X+
X     default:
X         printf("Unimplemented INT 13h function %02Xh\n",*bregs[AH]);
X #ifdef PANIC
X@@ -998,9 +1058,9 @@
X         exit_emu();
X #endif
X         break;
X-        }
X+    }
X 
X-    D(if (CF) printf("Operation failed\n"););
X+    D(if (CF) printf("Operation failed\n"); else printf("OK\n"););
X }
X 
X 
X@@ -1186,24 +1246,25 @@
X     memcpy(BIOS_base+0xe000,BIOSCOPYRIGHT, sizeof BIOSCOPYRIGHT);
X }
X 
X+static unsigned char diskparamhd[16];
X 
X void init_bios(void)
X {
X     int i;
X+    DiskTab *hd;
X #ifdef BOOT
X     DiskTab *boot;
X #endif
X-/*
X-*   for (i = 0; i < NUMHDISKS; i++)
X-*   {
X-*       if ((hdisk[i].fd = open(hdisk[i].name,O_RDWR)) < 0)
X-*       {
X-*           fprintf(stderr, "Cannot open hard disk %s :",hdisk[i].name);
X-*           perror(NULL);
X-*           exit(1);
X-*       }
X-*   }
X-*/
X+
X+    for (i = 0; i < NUMHDISKS; i++)
X+    {
X+        if ((hdisk[i].fd = open(hdisk[i].name,O_RDWR)) < 0)
X+        {
X+            fprintf(stderr, "Cannot open hard disk %s :",hdisk[i].name);
X+            perror(NULL);
X+            exit(1);
X+        }
X+    }
X     for (i = 0; i < NUMFDISKS; i++)
X     {
X         if ((fdisk[i].fd = open(fdisk[i].name,O_RDWR)) < 0)
X@@ -1236,6 +1297,29 @@
X     IF = 1;
X #endif
X 
X+#ifdef MK_HD_PARAMS
X+    hd = get_disk_tab(0x80);
X+    if (hd) {
X+	diskparamhd[0] = (hd->cylinders) & 0xff;
X+	diskparamhd[1] = (hd->cylinders) >> 8;
X+	diskparamhd[2] = (hd->heads);
X+	diskparamhd[3] = 0;
X+	diskparamhd[4] = 0;
X+	diskparamhd[5] = 0xff;
X+	diskparamhd[6] = 0xff;
X+	diskparamhd[7] = 0;
X+	diskparamhd[8] = 8;
X+	diskparamhd[9] = 0;
X+	diskparamhd[10] = 0;
X+	diskparamhd[11] = 0;
X+	diskparamhd[12] = (hd->cylinders) & 0xff;
X+	diskparamhd[13] = (hd->cylinders) >> 8;
X+	diskparamhd[14] = (hd->sectors);
X+	diskparamhd[15] = 0;
X+	set_int(0x41, diskparamhd, sizeof(diskparamhd), 0, 0, 0);
X+    }
X+#endif
X+
X #ifdef DEBUGGER
X     signal(SIGINT, (void *)debug_breakin);
X #else
X@@ -1257,6 +1341,11 @@
X }
X 
X 
X+char *set_hd(char *file, int hd)
X+{
X+}
X+
X+
X char *set_boot_type(int type)
X {
X     fdisk[0].heads = 2;
X@@ -1289,10 +1378,8 @@
X 
X void bios_off(void)
X {
X-/*  int i;
X-*    
X-*   for (i = 0; i < NUMHDISKS; i++)
X-*       close(hdisk[i].fd);
X-*/
X+  int i;
X+    
X+   for (i = 0; i < NUMHDISKS; i++)
X+       close(hdisk[i].fd);
X }
X-
END-of-patch-c3-hdemul
exit

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-ports->joerg 
Responsible-Changed-By: obrien 
Responsible-Changed-When: Tue Jul 28 11:09:47 PDT 1998 
Responsible-Changed-Why:  
joerg is the maintainer 
State-Changed-From-To: open->closed 
State-Changed-By: joerg 
State-Changed-When: Mon Feb 21 23:41:28 MET 2000 
State-Changed-Why:  
Some things take forever...  sorry Arne for the long delay. 
Finally integrated all of your patches (plus one of my own triggered 
by your harddisk work).  Tak! 
>Unformatted:
