diff options
-rw-r--r-- | memdisk/conio.h | 1 | ||||
-rw-r--r-- | memdisk/memdisk.asm | 51 | ||||
-rw-r--r-- | memdisk/setup.c | 74 |
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" */ |