summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--memdisk/conio.h1
-rw-r--r--memdisk/memdisk.asm51
-rw-r--r--memdisk/setup.c74
3 files changed, 54 insertions, 72 deletions
diff --git a/memdisk/conio.h b/memdisk/conio.h
index 93ad000e..6a5b7d9a 100644
--- a/memdisk/conio.h
+++ b/memdisk/conio.h
@@ -21,6 +21,7 @@
#define CONIO_H
#include <stdint.h>
+#include <stddef.h>
#include <stdarg.h>
int putchar(int);
diff --git a/memdisk/memdisk.asm b/memdisk/memdisk.asm
index 610af31d..11234501 100644
--- a/memdisk/memdisk.asm
+++ b/memdisk/memdisk.asm
@@ -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
diff --git a/memdisk/setup.c b/memdisk/setup.c
index eff2d47a..f8fbdf6f 100644
--- a/memdisk/setup.c
+++ b/memdisk/setup.c
@@ -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" */