DOS now boots floppy and harddisk, but something is still amiss...
authorhpa <hpa>
Sat, 15 Dec 2001 00:45:42 +0000 (00:45 +0000)
committerhpa <hpa>
Sat, 15 Dec 2001 00:45:42 +0000 (00:45 +0000)
memdisk/conio.h
memdisk/memdisk.asm
memdisk/setup.c

index 93ad000..6a5b7d9 100644 (file)
@@ -21,6 +21,7 @@
 #define CONIO_H
 
 #include <stdint.h>
+#include <stddef.h>
 #include <stdarg.h>
 
 int putchar(int);
index 610af31..1123450 100644 (file)
@@ -17,7 +17,7 @@
 ; 
 ; ****************************************************************************
 
-%define DEBUG_TRACERS                  ; Uncomment to get debugging tracers
+; %define DEBUG_TRACERS                        ; Uncomment to get debugging tracers
 
 %ifdef DEBUG_TRACERS
 
@@ -80,8 +80,6 @@ Int13Start:
                pop dx
                js .nomatch             ; If SF=0, we have a class match here
                jz .our_drive           ; If ZF=1, we have an exact match
-               cmp ah,08h              ; Is it Get Drive Parameters?
-               je .our_drive           ; If so always handle for our own class
                cmp dl,[cs:DriveNo]
                jb .nomatch             ; Drive < Our drive
                dec dl                  ; Drive > Our drive, adjust drive #
@@ -116,7 +114,10 @@ Done:              ; Standard routine for return
                mov P_AX,ax
 DoneWeird:
                TRACER 'D'
-               mov [LastStatus],ah
+               xor bx,bx
+               mov es,bx
+               mov bx,[StatusPtr]
+               mov [es:bx],ah          ; Save status
                and ah,ah
 
                lds ebx,[Stack]
@@ -133,7 +134,6 @@ DoneWeird:
 Reset:
                ; Reset affects multiple drives, so we need to pass it on
                TRACER 'R'
-               mov [LastStatus],al     ; Clear the status (AL = 0)
                pop ax                  ; Drop return address
                popad                   ; Restore all registers
                pop es
@@ -168,7 +168,10 @@ GetDriveType:
                jmp short DoneWeird     ; But don't stick it into P_AX
 
 GetStatus:
-               mov ah,[LastStatus]     ; Copy last status
+               xor ax,ax
+               mov es,ax
+               mov bx,[StatusPtr]
+               mov ah,[bx]             ; Copy last status
                ret
 
 Read:
@@ -201,14 +204,7 @@ success:
                ret
 
 GetParms:
-               ; This gets invoked even for other drives, so that
-               ; we can modify the drive count on return
                TRACER 'G'
-               mov dx,P_DX             ; The drive whose number we're stealing
-               cmp dl,[DriveNo]
-               jb .belowdrive
-               ja .abovedrive
-               TRACER 'M'
                mov dl,[DriveCnt]       ; Cached data
                mov P_DL,dl
                test byte [DriveNo],80h
@@ -232,31 +228,6 @@ GetParms:
                xor ax,ax
                ret
                
-               ; If another disk, just mangle DL on return
-.abovedrive:
-               TRACER 'A'
-               dec dl                  ; Adjust drive # to what the BIOS believes
-.belowdrive:
-               TRACER 'B'
-               mov di,P_DI
-               mov ax,P_ES
-               mov es,ax
-               mov bx,P_BX
-               mov cx,P_CX
-               mov ax,P_AX
-               pushf
-               call far [OldInt13]
-               inc dl                  ; Add ourselves to the count
-               mov P_AX,ax
-               mov P_BX,bx
-               mov P_CX,cx
-               mov P_DX,dx
-               mov P_DI,di
-               mov cx,es
-               mov P_ES,cx
-               TRACER 'R'
-               ret
-
                ; Set up registers as for a "Read", and compares against disk size
 setup_regs:
 
@@ -509,6 +480,7 @@ DriveNo             db 0                    ; Our drive number
 DriveType      db 0                    ; Our drive type (floppies)
 DriveCnt       db 0                    ; Drive count (from the BIOS)
                db 0                    ; Pad
+
 BPT            dd 0                    ; BIOS parameter table pointer (floppies)
 
 MyStack                dw 0                    ; Offset of stack
@@ -518,8 +490,7 @@ MyStack             dw 0                    ; Offset of stack
 Stack          dd 0                    ; Saved SS:ESP on invocation
                dw 0
 SavedAX                dw 0                    ; AX saved on invocation
-
-LastStatus     db 0                    ; Last return status
+StatusPtr      dw 0                    ; Where to save status (zeroseg ptr)
 
                alignb 4, db 0          ; We *MUST* end on a dword boundary
 
index eff2d47..f8fbdf6 100644 (file)
@@ -27,6 +27,15 @@ struct memdisk_header {
   uint16_t total_size;
 };
 
+/* The Disk Parameter Table is required on hard disks */
+struct dpt {
+  uint16_t max_cyl;            /* Max cylinder */
+  uint8_t max_head;            /* Max head */
+  uint8_t junk1[5];            /* Obsolete junk, leave at zero */
+  uint8_t ctrl;                        /* Control byte */
+  uint8_t junk2[7];            /* More obsolete junk */
+};
+
 struct patch_area {
   uint16_t cylinders;
   uint16_t heads;
@@ -49,19 +58,11 @@ struct patch_area {
   uint8_t  _pad1;
 
   uint16_t bpt_offs, bpt_seg;
+  uint16_t statusptr;
 
   uint16_t mystack;
 };
 
-/* The Disk Parameter Table is required on hard disks */
-struct dpt {
-  uint16_t max_cyl;            /* Max cylinder */
-  uint8_t max_head;            /* Max head */
-  uint8_t junk1[5];            /* Obsolete junk, leave at zero */
-  uint8_t ctrl;                        /* Control byte */
-  uint8_t junk2[7];            /* More obsolete junk */
-};
-
 /* This is the header in the boot sector/setup area */
 struct setup_header {
   char cmdline[0x1f1];
@@ -197,6 +198,7 @@ rdz_32(uint32_t addr)
 /* Addresses in the zero page */
 #define BIOS_INT13     (0x13*4) /* INT 13h vector */
 #define BIOS_INT15     (0x15*4) /* INT 15h vector */
+#define BIOS_INT40     (0x40*4) /* INT 13h vector */
 #define BIOS_INT41      (0x41*4) /* INT 41h vector */
 #define BIOS_INT46      (0x46*4) /* INT 46h vector */
 #define BIOS_BASEMEM   0x413    /* Amount of DOS memory */
@@ -458,6 +460,7 @@ uint32_t setup(void)
   pptr->sectors   = geometry->s;
   pptr->disksize  = geometry->sectors;
   pptr->diskbuf   = shdr->ramdisk_image;
+  pptr->statusptr = (geometry->driveno & 0x80) ? 0x474 : 0x441;
 
   /* The size is given by hptr->total_size plus the size of the
      E820 map -- 12 bytes per range; we may need as many as
@@ -514,23 +517,6 @@ uint32_t setup(void)
     ranges[--nranges].type = -1;
   }
 
-  /* Copy driver followed by E820 table */
-  asm volatile("pushw %%es ; "
-              "movw %0,%%es ; "
-              "cld ; "
-              "rep ; movsl %%ds:(%%si), %%es:(%%di) ; "
-              "movw %1,%%cx ; "
-              "movw %2,%%si ; "
-              "rep ; movsl %%ds:(%%si), %%es:(%%di) ; "
-              "popw %%es"
-              :: "r" (driverseg),
-              "r" ((uint16_t)((nranges+1)*3)), /* 3 dwords/range */
-              "r" ((uint16_t)&ranges),
-              "c" (bin_size >> 2),
-              "S" (&_binary_memdisk_bin_start),
-              "D" (0)
-              : "esi", "edi", "ecx");
-
   /* Query drive parameters of this type */
   {
     uint16_t bpt_es, bpt_di;
@@ -550,24 +536,46 @@ uint32_t setup(void)
                 : "esi", "ebx", "ebp");
 
     if ( cf ) {
+      printf("INT 13 08: Failure\n");
       pptr->drivecnt = 1;
       pptr->bpt_offs = pptr->bpt_seg = 0;
     } else {
+      printf("INT 13 08: Success, count = %u, BPT = %04x:%04x\n",
+            dl, bpt_es, bpt_di);
       pptr->drivecnt = dl+1;
       pptr->bpt_offs = bpt_di;
       pptr->bpt_seg  = bpt_es;
     }
   }
 
+  /* Copy driver followed by E820 table */
+  asm volatile("pushw %%es ; "
+              "movw %0,%%es ; "
+              "cld ; "
+              "rep ; movsl %%ds:(%%si), %%es:(%%di) ; "
+              "movw %1,%%cx ; "
+              "movw %2,%%si ; "
+              "rep ; movsl %%ds:(%%si), %%es:(%%di) ; "
+              "popw %%es"
+              :: "r" (driverseg),
+              "r" ((uint16_t)((nranges+1)*3)), /* 3 dwords/range */
+              "r" ((uint16_t)&ranges),
+              "c" (bin_size >> 2),
+              "S" (&_binary_memdisk_bin_start),
+              "D" (0)
+              : "esi", "edi", "ecx");
+
   /* Install the interrupt handlers */
-  printf("old: int13 = %08x  int15 = %08x\n",
-        rdz_32(BIOS_INT13), rdz_32(BIOS_INT15));
+  {
+    printf("old: int13 = %08x  int15 = %08x\n",
+          rdz_32(BIOS_INT13), rdz_32(BIOS_INT15));
 
-  wrz_32(BIOS_INT13, driverptr+hptr->int13_offs);
-  wrz_32(BIOS_INT15, driverptr+hptr->int15_offs);
+    wrz_32(BIOS_INT13, driverptr+hptr->int13_offs);
+    wrz_32(BIOS_INT15, driverptr+hptr->int15_offs);
 
-  printf("new: int13 = %08x  int15 = %08x\n",
-        rdz_32(BIOS_INT13), rdz_32(BIOS_INT15));
+    printf("new: int13 = %08x  int15 = %08x\n",
+          rdz_32(BIOS_INT13), rdz_32(BIOS_INT15));
+  }
 
   /* Update various BIOS magic data areas (gotta love this shit) */
 
@@ -575,6 +583,7 @@ uint32_t setup(void)
     /* Update BIOS hard disk count */
     wrz_8(BIOS_HD_COUNT, rdz_8(BIOS_HD_COUNT)+1);
   } else {
+#if 0                          /* Apparently this is NOT wanted... */
     /* Update BIOS floppy disk count */
     uint16_t equip = rdz_16(BIOS_EQUIP);
     if ( equip & 1 ) {
@@ -586,6 +595,7 @@ uint32_t setup(void)
       equip &= ~(3 << 6);
     }
     wrz_16(BIOS_EQUIP, equip);
+#endif
   }
 
   /* Reboot into the new "disk" */