Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


*** empty log message ***
Zheng Cui [Thu, 14 Aug 2008 18:22:45 +0000 (18:22 +0000)]
palacios/build/Makefile
palacios/include/geekos/bootinfo.h
palacios/include/geekos/defs.h
palacios/src/geekos/defs.asm
palacios/src/geekos/mem.c
palacios/src/geekos/setup.asm
palacios/src/vmboot/rombios/rombios.c

index 1f63eaa..a30077a 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for GeekOS kernel, userspace, and tools
 # Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.60 $
+# $Revision: 1.61 $
 
 # This is free software.  You are permitted to use,
 # redistribute, and modify it as specified in the file "COPYING".
@@ -49,7 +49,7 @@ DEBUG=1
 DEBUG_SECTIONS= 
 
 ifeq ($(DEBUG_ALL),1)
-  DEBUG_SECTIONS:= $(DEBUG_SECTIONS) -DDEBUG_SHADOW_PAGING -DDEBUG_CTRL_REGS -DDEBUG_INTERRUPTS -DDEBUG_IO -DDEBUG_KEYBOARD -DDEBUG_PIC -DDEBUG_PIT -DDEBUG_NVRAM -DDEBUG_EMULATOR -DDEBUG_GENERIC
+  DEBUG_SECTIONS:= $(DEBUG_SECTIONS) -DDEBUG_SHADOW_PAGING -DDEBUG_CTRL_REGS -DDEBUG_INTERRUPTS -DDEBUG_IO -DDEBUG_KEYBOARD -DDEBUG_PIC -DDEBUG_PIT -DDEBUG_NVRAM -DDEBUG_EMULATOR -DDEBUG_GENERIC 
 endif
 ifeq ($(DEBUG_SHADOW_PAGING),1)
 DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_SHADOW_PAGING
@@ -81,6 +81,9 @@ endif
 ifeq ($(DEBUG_EMULATOR),1)
 DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_EMULATOR
 endif
+ifeq ($(DEBUG_RAMDISK),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_RAMDISK
+endif
 
 
 ifeq ($(DEBUG),1)
@@ -114,6 +117,16 @@ endif
 #
 TCPSTACK=UIP
 
+#
+#RAMDISK
+#
+RAMDISK_SRCS=
+BOOT_FLAGS=
+
+ifeq ($(RAMDISK_BOOT),1)
+BOOT_FLAGS := $(BOOT_FLAGS) -DRAMDISK_BOOT
+RAMDISK_SRCS := ramdisk.c cdrom.c
+endif
 
 
 
@@ -214,7 +227,7 @@ VMM_OBJS := $(VMM_C_OBJS) $(VMM_ASM_OBJS)
 
 
 
-DEVICE_C_SRCS := generic.c keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c serial.c
+DEVICE_C_SRCS := generic.c keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c serial.c $(RAMDISK_SRCS)
 
 DEVICE_C_OBJS := $(DEVICE_C_SRCS:%.c=devices/%.o)
 
@@ -297,7 +310,7 @@ FD_SECTORS_PER_TRACK := $(PERL) $(PROJECT_ROOT)/scripts/numsecs_per_track
 # ----------------------------------------------------------------------
 
 # Flags used for all C source files
-GENERAL_OPTS := -O -Wall $(EXTRA_C_OPTS) $(VMM_FLAGS) -fPIC
+GENERAL_OPTS := -O -Wall $(EXTRA_C_OPTS) $(VMM_FLAGS) $(BOOT_FLAGS) -fPIC
 CC_GENERAL_OPTS := $(GENERAL_OPTS) -Werror 
 
 # Flags used for kernel C source files
@@ -432,7 +445,7 @@ geekos/setup.bin : geekos/kernel.bin $(PROJECT_ROOT)/src/geekos/setup.asm
                -DVMM_SIZE=`$(NUMSECS) geekos/kernel.bin` \
                $(PROJECT_ROOT)/src/geekos/setup.asm \
                -o $@
-       $(PAD) $@ 512
+       $(PAD) $@ 2048
 
 # Loadable (flat) kernel image.
 geekos/kernel.bin : geekos/kernel.exe
index c171095..b32afff 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Boot information structure, passed to kernel Main() routine
  * Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
@@ -14,6 +14,10 @@ struct Boot_Info {
   int bootInfoSize;     /* size of this struct; for versioning */
   int vmm_size;
   int memSizeKB;        /* number of KB, as reported by int 15h */
+
+  /*Zheng 08/02/2008*/
+  unsigned long ramdisk_image; /*ramdisk load addr*/ 
+  unsigned long ramdisk_size;
 };
 
 #endif  /* GEEKOS_BOOTINFO_H */
index c34de1a..ef19e51 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Misc. kernel definitions
  * Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
- * $Revision: 1.5 $
+ * $Revision: 1.6 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
 #define GEEKOS_DEFS_H
 
 
+/*Zheng 08/01/2008*/
+#define SYSSEG             0x1000
+#define COMMAND_LINE_SIZE  1024
 
+#define SETUPSECTS    4            /* default nr of setup-sectors */
+#define SYSSIZE       0x7f00       /* system size: # of 16-byte clicks */
+#define ROOT_DEV      0            /* ROOT_DEV is now written by "build" */
+#define SWAP_DEV      0            /* SWAP_DEV is now written by "build" */
 
 /*
  * Kernel code and data segment selectors.
@@ -63,7 +70,7 @@
 
 
 // Where we load the vm's kernel image (1MB)
-#define VM_KERNEL_TARGET (0x100000) 
+//#define VM_KERNEL_TARGET (0x100000) 
 
 
 
index 6c5ce15..73c65f4 100644 (file)
@@ -1,6 +1,6 @@
 ; Definitions for use in GeekOS boot code
 ; Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
-; $Revision: 1.8 $
+; $Revision: 1.9 $
 
 ; This is free software.  You are permitted to use,
 ; redistribute, and modify it as specified in the file "COPYING".
 %ifndef DEFS_ASM
 %define DEFS_ASM
 
-VM_KERNEL_TARGET       equ 0x100000
+;Zheng 08/01/2008
+SYSSEG equ 0x1000
+COMMAND_LINE_SIZE equ 1024
+
+SETUPSECTS      equ 4            ; /* default nr of setup-sectors */
+SYSSIZE         equ 0x7f00       ; /* system size: # of 16-byte clicks */
+ROOT_DEV        equ 0            ; /* ROOT_DEV is now written by "build" */
+SWAP_DEV        equ 0            ; /* SWAP_DEV is now written by "build" */
+
+;VM_KERNEL_TARGET      equ 0x100000
        
 ; BIOS loads the boot sector at offset 0 in this segment
 BOOTSEG equ 0x07C0
index b705425..904ae8b 100644 (file)
@@ -2,7 +2,7 @@
  * Physical memory allocation
  * Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
  * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
- * $Revision: 1.9 $
+ * $Revision: 1.10 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
  */
 struct Page* g_pageList;
 
+#ifdef RAMDISK_BOOT
+ulong_t g_ramdiskImage;
+ulong_t s_ramdiskSize;
+#endif
+
 /*
  * Number of pages currently available on the freelist.
  */
@@ -135,6 +140,14 @@ void Init_Mem(struct Boot_Info* bootInfo)
     ulong_t heapEnd;
     ulong_t vmmMemEnd;
 
+    /*Zheng 08/03/2008*/    
+#ifdef RAMDISK_BOOT
+    g_ramdiskImage = bootInfo->ramdisk_image;
+    s_ramdiskSize = bootInfo->ramdisk_size;
+    ulong_t initrdAddr;
+    ulong_t initrdEnd;
+#endif
+    
 
     KASSERT(bootInfo->memSizeKB > 0);
 
@@ -163,6 +176,7 @@ void Init_Mem(struct Boot_Info* bootInfo)
      *        Heap (512 Pages)
      *        Page List (variable pages)
      *        Available Memory for VMM (4096 pages)
+     *        Ramdisk //Zheng 08/03/2008
      *        VM Memory (everything else)
      */
 
@@ -188,12 +202,35 @@ void Init_Mem(struct Boot_Info* bootInfo)
     /* ** */
     vmmMemEnd = Round_Up_To_Page(pageListEnd + VMM_AVAIL_MEM_SIZE);
 
+#ifdef RAMDISK_BOOT
+    /*
+     * Zheng 08/03/2008
+     * copy the ramdisk to this area 
+     */
 
+    initrdAddr = vmmMemEnd;
+    initrdEnd = Round_Up_To_Page(initrdAddr + s_ramdiskSize);
+    PrintBoth("mem.c(%d) Move ramdisk(%dB) from %x to %x", __LINE__, s_ramdiskSize, g_ramdiskImage, initrdAddr);
+    memcpy(initrdAddr, g_ramdiskImage, s_ramdiskSize);
+    PrintBoth(" done\n");
+    PrintBoth("mem.c(%d) Set 0 to unused bytes in the last ramdisk page from %x to %x", __LINE__, initrdAddr+s_ramdiskSize, initrdEnd);
+    memset(initrdAddr+s_ramdiskSize, 0, initrdEnd-(initrdAddr+s_ramdiskSize));
+    PrintBoth(" done\n");
+    /*
+     * Zheng 08/03/2008
+     */
+    vm_range_start = initrdEnd;
+    vm_range_end = endOfMem;
+#else
+    
     /* 
      *  the disgusting way to get at the memory assigned to a VM
      */
+    
     vm_range_start = vmmMemEnd;
     vm_range_end = endOfMem;
+    
+#endif
 
     Add_Page_Range(0, PAGE_SIZE, PAGE_UNUSED);                        // BIOS area
     Add_Page_Range(PAGE_SIZE, PAGE_SIZE * 3, PAGE_ALLOCATED);         // Intial kernel thread obj + stack
@@ -202,12 +239,20 @@ void Init_Mem(struct Boot_Info* bootInfo)
     Add_Page_Range(KERNEL_START_ADDR, kernEnd, PAGE_KERN);            // VMM Kernel
     //    Add_Page_Range(guest_kernel_start, guestEnd, PAGE_VM);                  // Guest kernel location
     Add_Page_Range(heapAddr, heapEnd, PAGE_HEAP);                     // Heap
-    Add_Page_Range(pageListAddr, pageListEnd, PAGE_KERN);              // Page List 
-    Add_Page_Range(pageListEnd, vmmMemEnd, PAGE_AVAIL);                // Available VMM memory
-    //    Add_Page_Range(vmmMemEnd, endOfMem, PAGE_VM);                      // Memory allocated to the VM
-    // Until we get a more intelligent memory allocator
-    Add_Page_Range(vmmMemEnd, endOfMem, PAGE_AVAIL);                      // Memory allocated to the VM
+    Add_Page_Range(pageListAddr, pageListEnd, PAGE_KERN);             // Page List 
+    Add_Page_Range(pageListEnd, vmmMemEnd, PAGE_AVAIL);               // Available VMM memory
 
+#ifdef RAMDISK_BOOT
+    /*
+     * Zheng 08/03/2008
+     */
+    Add_Page_Range(vmmMemEnd, initrdEnd, PAGE_ALLOCATED);              //Ramdisk memory area      
+    //    Add_Page_Range(vmmMemEnd, endOfMem, PAGE_VM);                // Memory allocated to the VM
+    // Until we get a more intelligent memory allocator
+    Add_Page_Range(initrdEnd, endOfMem, PAGE_AVAIL);                   // Memory allocated to the VM
+#else
+    Add_Page_Range(vmmMemEnd, endOfMem, PAGE_AVAIL);                   // Memory allocated to the VM
+#endif
 
     /* Initialize the kernel heap */
     Init_Heap(heapAddr, KERNEL_HEAP_SIZE);
@@ -226,7 +271,17 @@ void Init_Mem(struct Boot_Info* bootInfo)
     PrintBoth("%x to %x - KERNEL HEAP\n", heapAddr, heapEnd - 1);
     PrintBoth("%lx to %lx - PAGE LIST\n", pageListAddr, pageListEnd - 1);
     PrintBoth("%lx to %x - FREE\n", pageListEnd, vmmMemEnd - 1);
+
+#ifdef RAMDISK_BOOT
+    /*
+     * Zheng 08/03/2008
+     */
+    PrintBoth("%lx to %x - RAMDISK\n", vmmMemEnd, initrdEnd - 1);
+
+    PrintBoth("%lx to %x - GUEST_MEMORY (also free)\n", initrdEnd, endOfMem - 1);
+#else
     PrintBoth("%lx to %x - GUEST_MEMORY (also free)\n", vmmMemEnd, endOfMem - 1);
+#endif
 }
 
 /*
index f4d0ae7..1ae2979 100644 (file)
@@ -1,7 +1,7 @@
 ; -*- fundamental -*-
 ; GeekOS setup code
 ; Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
-; $Revision: 1.4 $
+; $Revision: 1.5 $
 
 ; This is free software.  You are permitted to use,
 ; redistribute, and modify it as specified in the file "COPYING".
 ; modified by Bruce Evans (bde)
 ; adapted for Kernel Toolkit by Luigi Sgro
 
+%define __BIG_KERNEL__
+
 %include "defs.asm"
 
 [BITS 16]
 [ORG 0x0]
 
+start:
+               db      0xEB
+               db      46 ;trampoline
+
+; This is the setup header, and it must start at %cs:2 (old 0x9020:2)
+
+               db      'H'             ; header signature
+               db      'd'
+               db      'r'
+               db      'S'
+               dw      0x0203          ; header version number (>= 0x0105)
+                                       ; or else old loadlin-1.5 will fail)
+realmode_swtch:        dw      0, 0            ; default_switch, SETUPSEG
+start_sys_seg: dw      SYSSEG
+               dw      kernel_version  ; pointing to kernel version string
+                                       ; above section of header is compatible
+                                       ; with loadlin-1.5 (header v1.5). Don't
+                                       ; change it.
+
+type_of_loader:        db      0               ; = 0, old one (LILO, Loadlin,
+                                       ;      Bootlin, SYSLX, bootsect...)
+                                       ; See Documentation/i386/boot.txt for
+                                       ; assigned ids
+       
+; flags, unused bits must be zero (RFU) bit within loadflags
+loadflags:  db 1
+;LOADED_HIGH   equ 1                   ; If set, the kernel is loaded high
+;CAN_USE_HEAP  equ 0x80                        ; If set, the loader also has set
+                                       ; heap_end_ptr to tell how much
+                                       ; space behind setup.S can be used for
+                                       ; heap purposes.
+                                       ; Only the loader knows what is free
+;%ifndef __BIG_KERNEL__
+;              db      1
+;%else
+;              db      1
+;%endif
+
+setup_move_size: dw  0x8000            ; size to move, when setup is not
+                                       ; loaded at 0x90000. We will move setup 
+                                       ; to 0x90000 then just before jumping
+                                       ; into the kernel. However, only the
+                                       ; loader knows how much data behind
+                                       ; us also needs to be loaded.
+
+code32_start: dd 0x100000                              ; here loaders can put a different
+                                       ; start address for 32-bit code.
+;%ifndef __BIG_KERNEL__
+;              dd      0x100000        ;   0x1000 = default for zImage
+;%else
+;              dd      0x100000        ; 0x100000 = default for big kernel
+;%endif
+
+ramdisk_image: dd      0               ; address of loaded ramdisk image
+                                       ; Here the loader puts the 32-bit
+                                       ; address where it loaded the image.
+                                       ; This only will be read by the kernel.
+
+ramdisk_size:  dd      0               ; its size in bytes
+
+bootsect_kludge:
+               dd      0               ; obsolete
+
+heap_end_ptr:  dw      modelist+1024   ; (Header version 0x0201 or later)
+                                       ; space from here (exclusive) down to
+                                       ; end of setup code can be used by setup
+                                       ; for local heap purposes.
+
+pad1:          dw      0
+cmd_line_ptr:  dd      0               ; (Header version 0x0202 or later)
+                                       ; If nonzero, a 32-bit pointer
+                                       ; to the kernel command line.
+                                       ; The command line should be
+                                       ; located between the start of
+                                       ; setup and the end of low
+                                       ; memory (0xa0000), or it may
+                                       ; get overwritten before it
+                                       ; gets read.  If this field is
+                                       ; used, there is no longer
+                                       ; anything magical about the
+                                       ; 0x90000 segment; the setup
+                                       ; can be located anywhere in
+                                       ; low memory 0x10000 or higher.
+
+ramdisk_max:     dd 0xffffffff
+;kernel_alignment:  dd 0x200000          ; physical addr alignment required for
+                                       ; protected mode relocatable kernel
+;%ifdef CONFIG_RELOCATABLE
+;relocatable_kernel:    db 1
+;%else
+;relocatable_kernel:    db 0
+;%endif
+;pad2:                  db 0
+;pad3:                  dw 0
+
+;cmdline_size:   dd   COMMAND_LINE_SIZE-1     ;length of the command line,
+                                              ;added with boot protocol
+                                              ;version 2.06
+
+trampoline:    call    start_setup
+;              ALIGN 16
+space: 
+       %rep  1024
+                    db 0
+       %endrep                         ; The offset at this point is 0x240     
+                                       
+; End of setup header ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
 start_setup:
 
        ; Redefine the data segment so we can access variables
@@ -60,6 +171,7 @@ start_setup:
        mov     ax, 0x01
        lmsw    ax
 
+
        ; Jump to 32 bit code.
        jmp     dword KERNEL_CS:(SETUPSEG << 4) + setup_32
 
@@ -80,6 +192,16 @@ setup_32:
        ; Build Boot_Info struct on stack.
        ; Note that we push the fields on in reverse order,
        ; since the stack grows downwards.
+
+       ;Zheng 08/02/2008
+       xor eax, eax
+       mov eax, [(SETUPSEG<<4)+ramdisk_size]
+       push eax
+
+       xor eax, eax
+       mov eax, [(SETUPSEG<<4)+ramdisk_image]
+       push eax        
+
        xor     eax, eax
        mov     ax, [(SETUPSEG<<4)+mem_size_kbytes]
        xor     ebx, ebx
@@ -181,6 +303,7 @@ Enable_A20:
 mem_size_kbytes: dw 0
 mem_size_eblocks: dw 0
 
+
 ; ----------------------------------------------------------------------
 ; The GDT.  Creates flat 32-bit address space for the kernel
 ; code, data, and stack.  Note that this GDT is just used
@@ -229,3 +352,15 @@ GDT_Pointer:
 IDT_Pointer:
        dw 0
        dd 00
+
+; Here's a bunch of information about your current kernel..
+kernel_version:        db      "1.0.0VMMHack"
+               db      " ("
+               db      "copyright"
+               db      "@"
+               db      "2008"
+               db      ") "
+               db      ""
+               db      0
+
+modelist:
\ No newline at end of file
index a958848..4741deb 100644 (file)
@@ -1,6 +1,6 @@
 //  -*- fundamental -*-
 /////////////////////////////////////////////////////////////////////////
-// $Id: rombios.c,v 1.12 2008/07/11 22:59:38 pdinda Exp $
+// $Id: rombios.c,v 1.13 2008/08/14 18:22:45 cuizheng Exp $
 /////////////////////////////////////////////////////////////////////////
 //
 //  Copyright (C) 2002  MandrakeSoft S.A.
 
 #define DEBUG_ROMBIOS      1
 
+#define DEBUG_RAMDISK     0
 #define DEBUG_ATA          0
 #define DEBUG_INT13_HD     0
 #define DEBUG_INT13_CD     0
@@ -945,10 +946,10 @@ Bit16u cdrom_boot();
 
 #endif // BX_ELTORITO_BOOT
 
-static char bios_cvs_version_string[] = "$Revision: 1.12 $";
-static char bios_date_string[] = "$Date: 2008/07/11 22:59:38 $";
+static char bios_cvs_version_string[] = "$Revision: 1.13 $";
+static char bios_date_string[] = "$Date: 2008/08/14 18:22:45 $";
 
-static char CVSID[] = "$Id: rombios.c,v 1.12 2008/07/11 22:59:38 pdinda Exp $";
+static char CVSID[] = "$Id: rombios.c,v 1.13 2008/08/14 18:22:45 cuizheng Exp $";
 
 /* Offset to skip the CVS $Id: prefix */ 
 #define bios_version_string  (CVSID + 4)
@@ -973,6 +974,15 @@ static char CVSID[] = "$Id: rombios.c,v 1.12 2008/07/11 22:59:38 pdinda Exp $";
 #define BX_INFO(format, p...)   bios_printf(BIOS_PRINTF_INFO, format, ##p)
 #define BX_PANIC(format, p...)  bios_printf(BIOS_PRINTF_DEBHALT, format, ##p)
 
+/*Zheng 07/2008*/
+
+#if DEBUG_RAMDISK
+#   define debug_outb(a...) outb(a)
+#else
+#   define debug_outb(a...)
+#endif  
+
+
 #if DEBUG_ATA
 #  define BX_DEBUG_ATA(a...) BX_DEBUG(a)
 #else
@@ -2180,6 +2190,8 @@ void ata_detect( )
   Bit8u  hdcount, cdcount, device, type;
   Bit8u  buffer[0x0200];
 
+  debug_outb(0x3e8, 0xf0);
+
   //BX_DEBUG("rombios: ata_detect\n");
 
 #if BX_MAX_ATA_INTERFACES > 0
@@ -2436,6 +2448,8 @@ void ata_detect( )
           break;
         }
 
+       debug_outb(0x2ed, device);
+       debug_outb(0x2ee, type);
       switch (type) {
         case ATA_TYPE_ATA:
           printf("ata%d %s: ",channel,slave?" slave":"master");
@@ -2452,6 +2466,8 @@ void ata_detect( )
           break;
         case ATA_TYPE_UNKNOWN:
           printf("ata%d %s: Unknown device\n",channel,slave?" slave":"master");
+         if(device == 3) {
+         }
           break;
         }
       }
@@ -2463,6 +2479,7 @@ void ata_detect( )
   write_byte(0x40,0x75, hdcount);
  
   printf("\n");
+  debug_outb(0x3e8, 0xf0);
 
   // FIXME : should use bios=cmos|auto|disable bits
   // FIXME : should know about translation bits
@@ -2484,6 +2501,8 @@ Bit16u device;
   Bit8u  channel, slave, sn, sc; 
   Bit16u max;
 
+  debug_outb(0x3e9, 0xf1);
+
   channel = device / 2;
   slave = device % 2;
 
@@ -2533,6 +2552,8 @@ Bit16u device;
 
   // Enable interrupts
   outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
+
+  debug_outb(0x3e9, 0xf1);
 }
 
 // ---------------------------------------------------------------------------
@@ -2563,6 +2584,9 @@ Bit32u lba;
   Bit8u  channel, slave;
   Bit8u  status, current, mode;
 
+  debug_outb(0x3ea, 0xf2); 
+
+
   channel = device / 2;
   slave   = device % 2;
 
@@ -2606,9 +2630,11 @@ Bit32u lba;
 
   if (status & ATA_CB_STAT_ERR) {
     BX_DEBUG_ATA("ata_cmd_data_in : read error\n");
+      debug_outb(0x3ea, 0xf2); 
     return 2;
     } else if ( !(status & ATA_CB_STAT_DRQ) ) {
     BX_DEBUG_ATA("ata_cmd_data_in : DRQ not set (status %02x)\n", (unsigned) status);
+  debug_outb(0x3ea, 0xf2); 
     return 3;
   }
 
@@ -2667,6 +2693,7 @@ ASM_END
       if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 
           != ATA_CB_STAT_RDY ) {
         BX_DEBUG_ATA("ata_cmd_data_in : no sectors left (status %02x)\n", (unsigned) status);
+        debug_outb(0x3ea, 0xf2); 
         return 4;
         }
       break;
@@ -2675,6 +2702,7 @@ ASM_END
       if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 
           != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
         BX_DEBUG_ATA("ata_cmd_data_in : more sectors left (status %02x)\n", (unsigned) status);
+        debug_outb(0x3ea, 0xf2); 
         return 5;
       }
       continue;
@@ -2682,6 +2710,7 @@ ASM_END
   }
   // Enable interrupts
   outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
+  debug_outb(0x3ea, 0xf2); 
   return 0;
 }
 
@@ -2706,6 +2735,8 @@ Bit32u lba;
   Bit8u  channel, slave;
   Bit8u  status, current, mode;
 
+  debug_outb(0x3eb, 0xf3);
+
   channel = device / 2;
   slave   = device % 2;
 
@@ -2749,9 +2780,11 @@ Bit32u lba;
 
   if (status & ATA_CB_STAT_ERR) {
     BX_DEBUG_ATA("ata_cmd_data_out : read error\n");
+    debug_outb(0x3eb, 0xf3);
     return 2;
     } else if ( !(status & ATA_CB_STAT_DRQ) ) {
     BX_DEBUG_ATA("ata_cmd_data_out : DRQ not set (status %02x)\n", (unsigned) status);
+    debug_outb(0x3eb, 0xf3);
     return 3;
     }
 
@@ -2812,6 +2845,7 @@ ASM_END
       if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 
           != ATA_CB_STAT_RDY ) {
         BX_DEBUG_ATA("ata_cmd_data_out : no sectors left (status %02x)\n", (unsigned) status);
+       debug_outb(0x3eb, 0xf3);
         return 6;
         }
       break;
@@ -2820,6 +2854,7 @@ ASM_END
       if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 
           != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
         BX_DEBUG_ATA("ata_cmd_data_out : more sectors left (status %02x)\n", (unsigned) status);
+       debug_outb(0x3eb, 0xf3);
         return 7;
       }
       continue;
@@ -2827,6 +2862,7 @@ ASM_END
   }
   // Enable interrupts
   outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
+  debug_outb(0x3eb, 0xf3);
   return 0;
 }
 
@@ -2852,18 +2888,22 @@ Bit32u length;
   Bit8u  status, error, mode, lmode;
   Bit32u total, transfer;
 
+  debug_outb(0x3ec, 0xf4);
+
   channel = device / 2;
   slave = device % 2;
 
   // Data out is not supported yet
   if (inout == ATA_DATA_OUT) {
     BX_INFO("ata_cmd_packet: DATA_OUT not supported yet\n");
+  debug_outb(0x3ec, 0xf4);
     return 1;
     }
 
   // The header length must be even
   if (header & 1) {
     BX_DEBUG_ATA("ata_cmd_packet : header must be even (%04x)\n",header);
+  debug_outb(0x3ec, 0xf4);
     return 1;
     }
 
@@ -2914,7 +2954,7 @@ retry_on_media_change:
   // WAIT_FOR_NOT_BUSY_AND_DRIVE_READY();
   WAIT_FOR_NOT_BUSY();
    
-  //BX_DEBUG_ATA("ata_cmd_packet: not busy\n");
+  BX_DEBUG_ATA("ata_cmd_packet: not busy\n");
 
   // set "noninterruptable"
   outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
@@ -2928,24 +2968,24 @@ retry_on_media_change:
   outb(iobase1 + ATA_CB_SC, 0x00);
   outb(iobase1 + ATA_CB_SN, 0x00);
 
-  //BX_DEBUG_ATA("ata_cmd_packet: configuration done\n");
+  BX_DEBUG_ATA("ata_cmd_packet: configuration done\n");
 
   // Issue command for packet 
   outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET);
 
-  //BX_DEBUG_ATA("ata_cmd_packet: A0 issued to drive\n");
+  BX_DEBUG_ATA("ata_cmd_packet: A0 issued to drive\n");
  
   ALT_STATUS_WAIT_FOR((status&ATA_CB_STAT_BSY)==0);
 
-  //BX_DEBUG_ATA("ata_cmd_packet: alt status shows not busy\n");
+  BX_DEBUG_ATA("ata_cmd_packet: alt status shows not busy\n");
 
   STATUS_UPDATE();
 
-  //BX_DEBUG_ATA("ata_cmd_packet: main status shows 0x%x\n",(unsigned)status);
+  BX_DEBUG_ATA("ata_cmd_packet: main status shows 0x%x\n",(unsigned)status);
 
   WAIT_FOR_DATA_REQUEST();
 
-  //BX_DEBUG_ATA("ata_cmd_packet: data request is set\n");
+  BX_DEBUG_ATA("ata_cmd_packet: data request is set\n");
 
   // Normalize address
   cmdseg += (cmdoff / 16);
@@ -3031,6 +3071,7 @@ ASM_END
 #endif      
       if (status & ATA_CB_STAT_ERR) {
         BX_DEBUG_ATA("ata_cmd_packet : error (status %02x)\n",status);
+  debug_outb(0x3ec, 0xf4);
         return 3;
       }
       
@@ -3040,6 +3081,7 @@ ASM_END
       if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 
           != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
         BX_DEBUG_ATA("ata_cmd_packet 1: not ready (status %02x)\n", status);
+  debug_outb(0x3ec, 0xf4);
         return 4;
       }
       
@@ -3177,18 +3219,20 @@ ASM_END
       // Save transferred bytes count
       transfer += count;
       write_dword(ebda_seg, &EbdaData->ata.trsfbytes,transfer);
-      }
-    }
+      } //while(1)
+    }//else
 
   // Final check, device must be ready
   if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 
          != ATA_CB_STAT_RDY ) {
     BX_DEBUG_ATA("ata_cmd_packet 2 : not ready (status %02x)\n", (unsigned) status);
+  debug_outb(0x3ec, 0xf4);
        return 4;
     }
 
   // Enable interrupts
   outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
+  debug_outb(0x3ec, 0xf4);
   return 0;
 
 }
@@ -3210,18 +3254,24 @@ atapi_get_sense(device)
   Bit8u  buffer[16];
   Bit8u i;
 
+  debug_outb(0x3ed, 0xf5);
+
   memsetb(get_SS(),atacmd,0,12);
 
   // Request SENSE 
   atacmd[0]=0x03;    
   atacmd[4]=0x20;    
-  if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 16L, ATA_DATA_IN, get_SS(), buffer) != 0)
+  if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 16L, ATA_DATA_IN, get_SS(), buffer) != 0) {
+  debug_outb(0x3ed, 0xf5);
     return 0x0002;
+  }
 
   if ((buffer[0] & 0x7e) == 0x70) {
+       debug_outb(0x3ed, 0xf5);
     return (((Bit16u)buffer[2]&0x0f)*0x100)+buffer[12];
     }
 
+  debug_outb(0x3ed, 0xf5);
   return 0;
 }
 
@@ -3232,21 +3282,29 @@ atapi_is_ready(device)
   Bit8u  atacmd[12];
   Bit8u  buffer[];
 
+  debug_outb(0x3ee, 0xf6);
+
   memsetb(get_SS(),atacmd,0,12);
  
   // Test Unit Ready
-  if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 0L, ATA_DATA_NO, get_SS(), buffer) != 0)
+  if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 0L, ATA_DATA_NO, get_SS(), buffer) != 0) {
+     debug_outb(0x3ee, 0xf6);
     return 0x000f;
+    }
 
   if (atapi_get_sense(device) !=0 ) {
     memsetb(get_SS(),atacmd,0,12);
 
     // try to send Test Unit Ready again
-    if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 0L, ATA_DATA_NO, get_SS(), buffer) != 0)
+    if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 0L, ATA_DATA_NO, get_SS(), buffer) != 0) {
+      debug_outb(0x3ee, 0xf6);
       return 0x000f;
+      }
 
+    debug_outb(0x3ee, 0xf6);
     return atapi_get_sense(device);
     }
+  debug_outb(0x3ee, 0xf6);
   return 0;
 }
 
@@ -3254,17 +3312,28 @@ atapi_is_ready(device)
 atapi_is_cdrom(device)
   Bit8u device;
 {
+
+
   Bit16u ebda_seg=read_word(0x0040,0x000E);
 
-  if (device >= BX_MAX_ATA_DEVICES)
+  debug_outb(0x3ef, 0xf7);
+
+  if (device >= BX_MAX_ATA_DEVICES) {
+    debug_outb(0x3ef, 0xf7);
     return 0;
+    }
 
-  if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_ATAPI)
+  if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_ATAPI) {
+     debug_outb(0x3ef, 0xf7);
     return 0;
+    }
 
-  if (read_byte(ebda_seg,&EbdaData->ata.devices[device].device) != ATA_DEVICE_CDROM)
+  if (read_byte(ebda_seg,&EbdaData->ata.devices[device].device) != ATA_DEVICE_CDROM) {
+    debug_outb(0x3ef, 0xf7);
     return 0;
+    }
 
+    debug_outb(0x3ef, 0xf7);
   return 1;
 }
 
@@ -3283,27 +3352,39 @@ atapi_is_cdrom(device)
   void
 cdemu_init()
 {
+
+
   Bit16u ebda_seg=read_word(0x0040,0x000E);
 
+       debug_outb(0x2e8, 0xf8);
+
   //BX_DEBUG("rombios: cdemu_init\n");
 
   // the only important data is this one for now
   write_byte(ebda_seg,&EbdaData->cdemu.active,0x00);
+       debug_outb(0x2e8, 0xf8);
+
+
 }
 
   Bit8u
 cdemu_isactive()
 {
+
   Bit16u ebda_seg=read_word(0x0040,0x000E);
 
+       outb(0x2e9, 0xf9);
   return(read_byte(ebda_seg,&EbdaData->cdemu.active));
 }
 
   Bit8u
 cdemu_emulated_drive()
 {
+
   Bit16u ebda_seg=read_word(0x0040,0x000E);
 
+       debug_outb(0x2ea, 0xfa);
+       debug_outb(0x2ea, 0xfa);
   return(read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive));
 }
 
@@ -3321,6 +3402,7 @@ cdrom_boot()
   Bit16u boot_segment, nbsectors, i, error;
   Bit8u  device;
 
+  debug_outb(0x2eb, 0xfb);
 
   // Find out the first cdrom
   for (device=0; device<BX_MAX_ATA_DEVICES;device++) {
@@ -3328,7 +3410,10 @@ cdrom_boot()
     }
   
   // if not found
-  if(device >= BX_MAX_ATA_DEVICES) return 2;
+  if(device >= BX_MAX_ATA_DEVICES) {
+    debug_outb(0x2eb, 0xfb);
+      return 2;
+      }
 
 
 
@@ -3344,17 +3429,23 @@ cdrom_boot()
   atacmd[4]=(0x11 & 0x0000ff00) >> 8;
   atacmd[5]=(0x11 & 0x000000ff);
   atacmd[9]=atacmd[10]=atacmd[11]=0x0;  // just to be safe -PAD
-  if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0)
+  if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0) {
+    debug_outb(0x2eb, 0xfb);
     return 3;
+    }
 
 
   // Validity checks
   if(buffer[0]!=0)return 4;
   for(i=0;i<5;i++){
-    if(buffer[1+i]!=read_byte(0xf000,&isotag[i]))return 5;
+    if(buffer[1+i]!=read_byte(0xf000,&isotag[i])) {  
+    debug_outb(0x2eb, 0xfb); return 5;
+    }
    }
   for(i=0;i<23;i++)
-    if(buffer[7+i]!=read_byte(0xf000,&eltorito[i]))return 6;
+    if(buffer[7+i]!=read_byte(0xf000,&eltorito[i])) {  
+               debug_outb(0x2eb, 0xfb); return 6;
+       }
   
   // ok, now we calculate the Boot catalog address
   lba=buffer[0x4A]*0x1000000+buffer[0x49]*0x10000+buffer[0x48]*0x100+buffer[0x47];
@@ -3368,19 +3459,21 @@ cdrom_boot()
   atacmd[3]=(lba & 0x00ff0000) >> 16;
   atacmd[4]=(lba & 0x0000ff00) >> 8;
   atacmd[5]=(lba & 0x000000ff);
-  if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0)
+  if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0) {
+    debug_outb(0x2eb, 0xfb);
     return 7;
+    }
 
 
  
   // Validation entry
-  if(buffer[0x00]!=0x01)return 8;   // Header
-  if(buffer[0x01]!=0x00)return 9;   // Platform
-  if(buffer[0x1E]!=0x55)return 10;  // key 1
-  if(buffer[0x1F]!=0xAA)return 10;  // key 2
+  if(buffer[0x00]!=0x01) {  debug_outb(0x2eb, 0xfb); return 8;}   // Header
+  if(buffer[0x01]!=0x00){  debug_outb(0x2eb, 0xfb); return 9;}   // Platform
+  if(buffer[0x1E]!=0x55) {  debug_outb(0x2eb, 0xfb); return 10;}  // key 1
+  if(buffer[0x1F]!=0xAA) {  debug_outb(0x2eb, 0xfb); return 10;}  // key 2
 
   // Initial/Default Entry
-  if(buffer[0x20]!=0x88)return 11; // Bootable
+  if(buffer[0x20]!=0x88) {  debug_outb(0x2eb, 0xfb); return 11;} // Bootable
 
   write_byte(ebda_seg,&EbdaData->cdemu.media,buffer[0x21]);
   if(buffer[0x21]==0){
@@ -3417,8 +3510,10 @@ cdrom_boot()
   atacmd[3]=(lba & 0x00ff0000) >> 16;
   atacmd[4]=(lba & 0x0000ff00) >> 8;
   atacmd[5]=(lba & 0x000000ff);
-  if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, nbsectors*512L, ATA_DATA_IN, boot_segment,0)) != 0)
+  if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, nbsectors*512L, ATA_DATA_IN, boot_segment,0)) != 0) {
+    debug_outb(0x2eb, 0xfb);
     return 12;
+    }
 
 
   // Remember the media type
@@ -3460,6 +3555,7 @@ cdrom_boot()
     write_byte(ebda_seg,&EbdaData->cdemu.active,0x01);
 
   // return the boot drive + no error
+  debug_outb(0x2eb, 0xfb);
   return (read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive)*0x100)+0;
 }
 
@@ -4931,6 +5027,7 @@ int13_harddisk(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
   Bit16u size, count;
   Bit8u  device, status;
 
+  debug_outb(0x2ef, 0xff);
   BX_DEBUG_INT13_HD("int13_harddisk: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
 
   write_byte(0x0040, 0x008e, 0);  // clear completion flag
@@ -5300,6 +5397,7 @@ int13_fail_noah:
     SET_DISK_RET_STATUS(GET_AH());
 int13_fail_nostatus:
     SET_CF();     // error occurred
+  debug_outb(0x2ef, 0xff);
     return;
 
 int13_success:
@@ -5307,6 +5405,7 @@ int13_success:
 int13_success_noah:
     SET_DISK_RET_STATUS(0x00);
     CLEAR_CF();   // no error
+  debug_outb(0x2ef, 0xff);
     return;
 }
 
@@ -5324,6 +5423,8 @@ int13_cdrom(EHBX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
   Bit32u lba;
   Bit16u count, segment, offset, i, size;
 
+  debug_outb(0x2f8, 0xe0);
+
   BX_DEBUG_INT13_CD("int13_cdrom: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
   // BX_DEBUG_INT13_CD("int13_cdrom: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n",get_SS(), DS, ES, DI, SI);
   
@@ -5650,6 +5751,7 @@ int13_fail_noah:
     SET_DISK_RET_STATUS(GET_AH());
 int13_fail_nostatus:
     SET_CF();     // error occurred
+  debug_outb(0x2f8, 0xe0);
     return;
 
 int13_success:
@@ -5657,6 +5759,7 @@ int13_success:
 int13_success_noah:
     SET_DISK_RET_STATUS(0x00);
     CLEAR_CF();   // no error
+  debug_outb(0x2f8, 0xe0);
     return;
 }
 
@@ -5675,6 +5778,8 @@ int13_eltorito(DS, ES, DI, SI, BP, SP, BX, DX, CX, AX, IP, CS, FLAGS)
 {
   Bit16u ebda_seg=read_word(0x0040,0x000E);
 
+  debug_outb(0x2fa, 0xe2);
+
   BX_DEBUG_INT13_ET("int13_eltorito: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
   // BX_DEBUG_INT13_ET("int13_eltorito: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n",get_SS(), DS, ES, DI, SI);
   
@@ -5722,12 +5827,14 @@ int13_fail:
     SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
     SET_DISK_RET_STATUS(GET_AH());
     SET_CF();     // error occurred
+  debug_outb(0x2fa, 0xe2);
     return;
 
 int13_success:
     SET_AH(0x00); // no error
     SET_DISK_RET_STATUS(0x00);
     CLEAR_CF();   // no error
+  debug_outb(0x2fa, 0xe2);
     return;
 }
 
@@ -5751,6 +5858,8 @@ int13_cdemu(DS, ES, DI, SI, BP, SP, BX, DX, CX, AX, IP, CS, FLAGS)
   Bit16u before, segment, offset;
   Bit8u  atacmd[12];
 
+  debug_outb(0x2f9, 0xe1);
+
   BX_DEBUG_INT13_ET("int13_cdemu: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
   //BX_DEBUG_INT13_ET("int13_cdemu: SS=%04x ES=%04x DI=%04x SI=%04x\n", get_SS(), ES, DI, SI);
   
@@ -5926,6 +6035,7 @@ int13_fail_noah:
     SET_DISK_RET_STATUS(GET_AH());
 int13_fail_nostatus:
     SET_CF();     // error occurred
+  debug_outb(0x2f9, 0xe1);
     return;
 
 int13_success:
@@ -5933,6 +6043,7 @@ int13_success:
 int13_success_noah:
     SET_DISK_RET_STATUS(0x00);
     CLEAR_CF();   // no error
+  debug_outb(0x2f9, 0xe1);
     return;
 }
 
@@ -6018,6 +6129,8 @@ int13_harddisk(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
   Bit32u   lba;
   Bit16u   error;
 
+
+  debug_outb(0x2ef, 0xff);
   BX_DEBUG_INT13_HD("int13 harddisk: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
 
   write_byte(0x0040, 0x008e, 0);  // clear completion flag
@@ -6036,6 +6149,7 @@ int13_harddisk(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
     SET_AH(0x01);
     SET_DISK_RET_STATUS(0x01);
     SET_CF(); /* error occurred */
+  debug_outb(0x2ef, 0xff);
     return;
     }
 
@@ -6050,6 +6164,7 @@ BX_DEBUG_INT13_HD("int13_f00\n");
       set_diskette_current_cyl(0, 0); /* current cylinder, diskette 1 */
       set_diskette_current_cyl(1, 0); /* current cylinder, diskette 2 */
       CLEAR_CF(); /* successful */
+  debug_outb(0x2ef, 0xff);
       return;
       break;
 
@@ -6061,6 +6176,7 @@ BX_DEBUG_INT13_HD("int13_f01\n");
       /* set CF if error status read */
       if (status) SET_CF();
       else        CLEAR_CF();
+  debug_outb(0x2ef, 0xff);     
       return;
       break;
 
@@ -6101,24 +6217,31 @@ BX_DEBUG_INT13_HD("int13_f01\n");
         SET_AH(1);
         SET_DISK_RET_STATUS(1);
         SET_CF(); /* error occurred */
+  debug_outb(0x2ef, 0xff);
         return;
         }
 
-      if ( (num_sectors > 128) || (num_sectors == 0) )
+      if ( (num_sectors > 128) || (num_sectors == 0) ){
+  debug_outb(0x2ef, 0xff); 
         BX_PANIC("int13_harddisk(): num_sectors out of range!\n");
+       }
 
-      if (head > 15)
+      if (head > 15) {
+  debug_outb(0x2ef, 0xff);
         BX_PANIC("hard drive BIOS:(read/verify) head > 15\n");
+       }       
 
       if ( GET_AH() == 0x04 ) {
         SET_AH(0);
         SET_DISK_RET_STATUS(0);
         CLEAR_CF();
+  debug_outb(0x2ef, 0xff);
         return;
         }
 
       status = inb(0x1f7);
       if (status & 0x80) {
+  debug_outb(0x2ef, 0xff);
         BX_PANIC("hard drive BIOS:(read/verify) BUSY bit set\n");
         }
       outb(0x01f2, num_sectors);
@@ -6141,8 +6264,10 @@ BX_DEBUG_INT13_HD("CHS: %x %x %x\n", cylinder, head, sector);
         }
 
       if (status & 0x01) {
+        debug_outb(0x2ef, 0xff);
         BX_PANIC("hard drive BIOS:(read/verify) read error\n");
       } else if ( !(status & 0x08) ) {
+        debug_outb(0x2ef, 0xff);  
         BX_DEBUG_INT13_HD("status was %02x\n", (unsigned) status);
         BX_PANIC("hard drive BIOS:(read/verify) expected DRQ=1\n");
       }
@@ -6191,12 +6316,14 @@ ASM_END
         if (num_sectors == 0) {
           status = inb(0x1f7);
           if ( (status & 0xc9) != 0x40 )
+           debug_outb(0x2ef, 0xff);
             BX_PANIC("no sectors left to read/verify, status is %02x\n", (unsigned) status);
           break;
           }
         else {
           status = inb(0x1f7);
           if ( (status & 0xc9) != 0x48 )
+           debug_outb(0x2ef, 0xff);
             BX_PANIC("more sectors left to read/verify, status is %02x\n", (unsigned) status);
           continue;
           }
@@ -6206,6 +6333,7 @@ ASM_END
       SET_DISK_RET_STATUS(0);
       SET_AL(sector_count);
       CLEAR_CF(); /* successful */
+        debug_outb(0x2ef, 0xff);
       return;
       break;
 
@@ -6247,17 +6375,23 @@ BX_DEBUG_INT13_HD("int13_f03\n");
         SET_AH( 1);
         SET_DISK_RET_STATUS(1);
         SET_CF(); /* error occurred */
+         debug_outb(0x2ef, 0xff);  
         return;
         }
 
-      if ( (num_sectors > 128) || (num_sectors == 0) )
+      if ( (num_sectors > 128) || (num_sectors == 0) ) {
+        debug_outb(0x2ef, 0xff);
         BX_PANIC("int13_harddisk(): num_sectors out of range!\n");
+       }
 
-      if (head > 15)
+      if (head > 15) {
+        debug_outb(0x2ef, 0xff);
         BX_PANIC("hard drive BIOS:(read) head > 15\n");
+       }
 
       status = inb(0x1f7);
       if (status & 0x80) {
+        debug_outb(0x2ef, 0xff);
         BX_PANIC("hard drive BIOS:(read) BUSY bit set\n");
         }
 // should check for Drive Ready Bit also in status reg
@@ -6283,6 +6417,7 @@ BX_DEBUG_INT13_HD("CHS (write): %x %x %x\n", cylinder, head, sector);
         }
 
       if ( !(status & 0x08) ) {
+        debug_outb(0x2ef, 0xff);
         BX_DEBUG_INT13_HD("status was %02x\n", (unsigned) status);
         BX_PANIC("hard drive BIOS:(write) data-request bit not set\n");
         }
@@ -6330,14 +6465,18 @@ ASM_END
         num_sectors--;
         if (num_sectors == 0) {
           status = inb(0x1f7);
-          if ( (status & 0xe9) != 0x40 )
+          if ( (status & 0xe9) != 0x40 ) {
+           debug_outb(0x2ef, 0xff);
             BX_PANIC("no sectors left to write, status is %02x\n", (unsigned) status);
+           }
           break;
           }
         else {
           status = inb(0x1f7);
-          if ( (status & 0xc9) != 0x48 )
-            BX_PANIC("more sectors left to write, status is %02x\n", (unsigned) status);
+          if ( (status & 0xc9) != 0x48 ) {
+           debug_outb(0x2ef, 0xff);
+            BX_PANIC("more sectors left to write, status is %02x\n", (unsigned) status); 
+           }
           continue;
           }
         }
@@ -6346,6 +6485,7 @@ ASM_END
       SET_DISK_RET_STATUS(0);
       SET_AL(sector_count);
       CLEAR_CF(); /* successful */
+        debug_outb(0x2ef, 0xff);
       return;
       break;
 
@@ -6356,6 +6496,7 @@ BX_DEBUG_INT13_HD("int13_f05\n");
       SET_AH(0);
       SET_DISK_RET_STATUS(0);
       CLEAR_CF(); /* successful */
+        debug_outb(0x2ef, 0xff);
       return;
       break;
 
@@ -6397,7 +6538,7 @@ BX_DEBUG_INT13_HD("int13_f08\n");
       SET_AH(0);
       SET_DISK_RET_STATUS(0);
       CLEAR_CF(); /* successful */
-
+        debug_outb(0x2ef, 0xff);
       return;
       break;
 
@@ -6406,6 +6547,7 @@ BX_DEBUG_INT13_HD("int13_f09\n");
       SET_AH(0);
       SET_DISK_RET_STATUS(0);
       CLEAR_CF(); /* successful */
+        debug_outb(0x2ef, 0xff);
       return;
       break;
 
@@ -6413,6 +6555,7 @@ BX_DEBUG_INT13_HD("int13_f09\n");
 BX_DEBUG_INT13_HD("int13_f0a\n");
     case 0x0b: /* write disk sectors with ECC */
 BX_DEBUG_INT13_HD("int13_f0b\n");
+         debug_outb(0x2ef, 0xff);
       BX_PANIC("int13h Functions 0Ah & 0Bh not implemented!\n");
       return;
       break;
@@ -6423,6 +6566,7 @@ BX_DEBUG_INT13_HD("int13_f0c\n");
       SET_AH(0);
       SET_DISK_RET_STATUS(0);
       CLEAR_CF(); /* successful */
+         debug_outb(0x2ef, 0xff);
       return;
       break;
 
@@ -6431,6 +6575,7 @@ BX_DEBUG_INT13_HD("int13_f0d\n");
       SET_AH(0);
       SET_DISK_RET_STATUS(0);
       CLEAR_CF(); /* successful */
+         debug_outb(0x2ef, 0xff);
       return;
       break;
 
@@ -6448,12 +6593,14 @@ BX_DEBUG_INT13_HD("int13_f10\n");
         SET_AH(0);
         SET_DISK_RET_STATUS(0);
         CLEAR_CF(); // drive ready
+         debug_outb(0x2ef, 0xff);
         return;
         }
       else {
         SET_AH(0xAA);
         SET_DISK_RET_STATUS(0xAA);
         SET_CF(); // not ready
+         debug_outb(0x2ef, 0xff);
         return;
         }
       break;
@@ -6463,6 +6610,7 @@ BX_DEBUG_INT13_HD("int13_f11\n");
       SET_AH(0);
       SET_DISK_RET_STATUS(0);
       CLEAR_CF(); /* successful */
+         debug_outb(0x2ef, 0xff);
       return;
       break;
 
@@ -6472,6 +6620,7 @@ BX_DEBUG_INT13_HD("int13_f14\n");
       SET_DISK_RET_STATUS(0);
       CLEAR_CF(); /* successful */
       SET_AL(0);
+         debug_outb(0x2ef, 0xff);
       return;
       break;
 
@@ -6497,6 +6646,7 @@ ASM_END
       SET_AH(3);  // hard disk accessible
       SET_DISK_RET_STATUS(0); // ??? should this be 0
       CLEAR_CF(); // successful
+         debug_outb(0x2ef, 0xff);
       return;
       break;
 
@@ -6516,6 +6666,7 @@ ASM_END
       SET_AH(1);  // code=invalid function in AH or invalid parameter
       SET_DISK_RET_STATUS(1);
       SET_CF(); /* unsuccessful */
+         debug_outb(0x2ef, 0xff);
       return;
       break;
     }
@@ -6818,7 +6969,7 @@ int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
   Bit8u  drive_type, num_floppies, ah;
   Bit16u es, last_addr;
 
-
+  debug_outb(0x2fb, 0xe3);     
   //printf("int13_diskette: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
   BX_DEBUG_INT13_FL("int13_diskette: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n",get_SS(),get_DS(), ES, DI, SI);
 
@@ -6832,6 +6983,7 @@ int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
         SET_AH(1); // invalid param
         set_diskette_ret_status(1);
         SET_CF();
+         debug_outb(0x2fb, 0xe3);      
         return;
         }
       drive_type = inb_cmos(0x10);
@@ -6844,12 +6996,14 @@ int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
         SET_AH(0x80); // drive not responding
         set_diskette_ret_status(0x80);
         SET_CF();
+         debug_outb(0x2fb, 0xe3);      
         return;
         }
       SET_AH(0);
       set_diskette_ret_status(0);
       CLEAR_CF(); // successful
       set_diskette_current_cyl(drive, 0); // current cylinder
+        debug_outb(0x2fb, 0xe3);       
       return;
 
     case 0x01: // Read Diskette Status
@@ -6859,6 +7013,7 @@ int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
       if (val8) {
         SET_CF();
         }
+         debug_outb(0x2fb, 0xe3);      
       return;
 
     case 0x02: // Read Diskette Sectors
@@ -6877,6 +7032,7 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
         set_diskette_ret_status(1);
         SET_AL(0); // no sectors read
         SET_CF(); // error occurred
+         debug_outb(0x2fb, 0xe3);      
         return;
         }
 
@@ -6886,6 +7042,7 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
         set_diskette_ret_status(0x80);
         SET_AL(0); // no sectors read
         SET_CF(); // error occurred
+         debug_outb(0x2fb, 0xe3);      
         return;
         }
 
@@ -6896,6 +7053,7 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
           set_diskette_ret_status(0x0C);
           SET_AL(0); // no sectors read
           SET_CF(); // error occurred
+           debug_outb(0x2fb, 0xe3);    
           return;
           }
         }
@@ -6927,6 +7085,7 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
           set_diskette_ret_status(0x09);
           SET_AL(0); // no sectors read
           SET_CF(); // error occurred
+           debug_outb(0x2fb, 0xe3);    
           return;
           }
 
@@ -6981,8 +7140,10 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
 
         // check port 3f4 for drive readiness
         val8 = inb(0x3f4);
-        if ( (val8 & 0xf0) != 0x80 )
+        if ( (val8 & 0xf0) != 0x80 ) {
+         debug_outb(0x2fb, 0xe3);      
           BX_PANIC("int13_diskette:f02: ctrl not ready\n");
+         }
 
         // send read-normal-data command (9 bytes) to controller
         outb(0x03f5, 0xe6); // e6: read normal data
@@ -7019,8 +7180,10 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
 
         // check port 3f4 for accessibility to status bytes
         val8 = inb(0x3f4);
-        if ( (val8 & 0xc0) != 0xc0 )
+        if ( (val8 & 0xc0) != 0xc0 ) {
+         debug_outb(0x2fb, 0xe3);      
           BX_PANIC("int13_diskette: ctrl not ready\n");
+         }
 
         // read 7 return status bytes from controller
         // using loop index broken, have to unroll...
@@ -7045,6 +7208,7 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
           set_diskette_ret_status(0x20);
           SET_AL(0); // no sectors read
           SET_CF(); // error occurred
+           debug_outb(0x2fb, 0xe3);    
           return;
           }
 
@@ -7053,6 +7217,7 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
         // AL = number of sectors read (same value as passed)
         SET_AH(0x00); // success
         CLEAR_CF();   // success
+         debug_outb(0x2fb, 0xe3);      
         return;
         }
       else if (ah == 0x03) {
@@ -7082,6 +7247,7 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
           set_diskette_ret_status(0x09);
           SET_AL(0); // no sectors read
           SET_CF(); // error occurred
+           debug_outb(0x2fb, 0xe3);    
           return;
           }
 
@@ -7129,8 +7295,10 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
 
         // check port 3f4 for drive readiness
         val8 = inb(0x3f4);
-        if ( (val8 & 0xf0) != 0x80 )
+        if ( (val8 & 0xf0) != 0x80 ){
+         debug_outb(0x2fb, 0xe3);      
           BX_PANIC("int13_diskette:f03: ctrl not ready\n");
+         }
 
         // send read-normal-data command (9 bytes) to controller
         outb(0x03f5, 0xc5); // c5: write normal data
@@ -7167,8 +7335,10 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
 
         // check port 3f4 for accessibility to status bytes
         val8 = inb(0x3f4);
-        if ( (val8 & 0xc0) != 0xc0 )
+        if ( (val8 & 0xc0) != 0xc0 ) {
+         debug_outb(0x2fb, 0xe3);      
           BX_PANIC("int13_diskette: ctrl not ready\n");
+         }
 
         // read 7 return status bytes from controller
         // using loop index broken, have to unroll...
@@ -7195,8 +7365,10 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
             // AL=number of sectors written=0
             AX = 0x0300;
             SET_CF();
+             debug_outb(0x2fb, 0xe3);  
             return;
           } else {
+           debug_outb(0x2fb, 0xe3);    
             BX_PANIC("int13_diskette_function: read error\n");
           }
         }
@@ -7206,6 +7378,7 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
         // AL = number of sectors read (same value as passed)
         SET_AH(0x00); // success
         CLEAR_CF();   // success
+         debug_outb(0x2fb, 0xe3);      
         return;
         }
       else {  // if (ah == 0x04)
@@ -7216,6 +7389,7 @@ BX_INFO("floppy: drive>1 || head>1 ...\n");
         // AL = number of sectors verified (same value as passed)
         CLEAR_CF();   // success
         SET_AH(0x00); // success
+         debug_outb(0x2fb, 0xe3);      
         return;
         }
 
@@ -7240,6 +7414,7 @@ BX_DEBUG_INT13_FL("floppy f05\n");
         SET_AH(0x80); // drive not responding
         set_diskette_ret_status(0x80);
         SET_CF(); // error occurred
+         debug_outb(0x2fb, 0xe3);      
         return;
         }
 
@@ -7250,6 +7425,7 @@ BX_DEBUG_INT13_FL("floppy f05\n");
           set_diskette_ret_status(0x0C);
           SET_AL(0); // no sectors read
           SET_CF(); // error occurred
+           debug_outb(0x2fb, 0xe3);    
           return;
           }
         }
@@ -7272,6 +7448,7 @@ BX_DEBUG_INT13_FL("floppy f05\n");
         set_diskette_ret_status(0x09);
         SET_AL(0); // no sectors read
         SET_CF(); // error occurred
+         debug_outb(0x2fb, 0xe3);      
         return;
         }
 
@@ -7307,8 +7484,10 @@ BX_DEBUG_INT13_FL("floppy f05\n");
 
       // check port 3f4 for drive readiness
       val8 = inb(0x3f4);
-      if ( (val8 & 0xf0) != 0x80 )
+      if ( (val8 & 0xf0) != 0x80 ) {
+        debug_outb(0x2fb, 0xe3);       
         BX_PANIC("int13_diskette:f05: ctrl not ready\n");
+       }
 
       // send read-normal-data command (6 bytes) to controller
       outb(0x03f5, 0x4d); // 4d: format track
@@ -7337,8 +7516,10 @@ BX_DEBUG_INT13_FL("floppy f05\n");
       write_byte(0x0000, 0x043e, val8);
       // check port 3f4 for accessibility to status bytes
       val8 = inb(0x3f4);
-      if ( (val8 & 0xc0) != 0xc0 )
+      if ( (val8 & 0xc0) != 0xc0 ) {
+        debug_outb(0x2fb, 0xe3);       
         BX_PANIC("int13_diskette: ctrl not ready\n");
+       }
 
       // read 7 return status bytes from controller
       // using loop index broken, have to unroll...
@@ -7365,8 +7546,10 @@ BX_DEBUG_INT13_FL("floppy f05\n");
           // AL=number of sectors written=0
           AX = 0x0300;
           SET_CF();
+           debug_outb(0x2fb, 0xe3);    
           return;
         } else {
+         debug_outb(0x2fb, 0xe3);      
           BX_PANIC("int13_diskette_function: write error\n");
         }
       }
@@ -7375,6 +7558,7 @@ BX_DEBUG_INT13_FL("floppy f05\n");
       set_diskette_ret_status(0);
       set_diskette_current_cyl(drive, 0);
       CLEAR_CF(); // successful
+        debug_outb(0x2fb, 0xe3);       
       return;
 
 
@@ -7391,6 +7575,7 @@ BX_DEBUG_INT13_FL("floppy f08\n");
         DI = 0;
         SET_DL(num_floppies);
         SET_CF();
+         debug_outb(0x2fb, 0xe3);      
         return;
         }
 
@@ -7459,6 +7644,7 @@ BX_DEBUG_INT13_FL("floppy f08\n");
           break;
 
         default: // ?
+         debug_outb(0x2fb, 0xe3);      
           BX_PANIC("floppy: int13: bad floppy type\n");
         }
 
@@ -7473,6 +7659,7 @@ ASM_START
 ASM_END
       CLEAR_CF(); // success
       /* disk status not changed upon success */
+        debug_outb(0x2fb, 0xe3);       
       return;
 
 
@@ -7483,6 +7670,7 @@ BX_DEBUG_INT13_FL("floppy f15\n");
         SET_AH(0); // only 2 drives supported
         // set_diskette_ret_status here ???
         SET_CF();
+         debug_outb(0x2fb, 0xe3);      
         return;
         }
       drive_type = inb_cmos(0x10);
@@ -7508,12 +7696,14 @@ BX_DEBUG_INT13_FL("floppy f16\n");
         SET_AH(0x01); // invalid drive
         set_diskette_ret_status(0x01);
         SET_CF();
+         debug_outb(0x2fb, 0xe3);      
         return;
         }
 
       SET_AH(0x06); // change line not supported
       set_diskette_ret_status(0x06);
       SET_CF();
+        debug_outb(0x2fb, 0xe3);       
       return;
 
     case 0x17: // set diskette type for format(old)
@@ -7522,6 +7712,7 @@ BX_DEBUG_INT13_FL("floppy f17\n");
       SET_AH(0x01); // not supported
       set_diskette_ret_status(1); /* not supported */
       SET_CF();
+        debug_outb(0x2fb, 0xe3);       
       return;
 
     case 0x18: // set diskette type for format(new)
@@ -7529,6 +7720,7 @@ BX_DEBUG_INT13_FL("floppy f18\n");
       SET_AH(0x01); // do later
       set_diskette_ret_status(1);
       SET_CF();
+        debug_outb(0x2fb, 0xe3);       
       return;
 
     default:
@@ -7538,6 +7730,7 @@ BX_DEBUG_INT13_FL("floppy f18\n");
         SET_AH(0x01); // ???
         set_diskette_ret_status(1);
         SET_CF();
+         debug_outb(0x2fb, 0xe3);      
         return;
       //   }
     }
@@ -7558,6 +7751,7 @@ int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
       if (val8) {
         SET_CF();
         }
+         debug_outb(0x2fb, 0xe3);      
       return;
 
     default:
@@ -7565,6 +7759,7 @@ int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
       write_byte(0x0000, 0x0441, 0x01);
       SET_AH(0x01);
     }
+      debug_outb(0x2fb, 0xe3); 
 }
 #endif  // #if BX_SUPPORT_FLOPPY
 
@@ -8442,6 +8637,16 @@ hard_drive_post:
   // IRQ 14 = INT 76h
   // INT 76h calls INT 15h function ax=9100
 
+#if DEBUG_RAMDISK
+
+  mov al, #0xfc
+  mov dx, #0x02ec
+  out dx, al
+  mov ax, #0x0000
+  mov dx, #0x0000
+
+#endif
+
   mov  al, #0x0a   ; 0000 1010 = reserved, disable IRQ 14
   mov  dx, #0x03f6
   out  dx, al