diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-07-30 11:24:25 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-07-30 11:24:25 -0700 |
commit | 44bc900a31b8c83a4de92c45e0401ceaefe371e8 (patch) | |
tree | 7a49f7cb47d6b7afeb623bbfcba107411bb83de7 | |
parent | 3cdc491e358508621ce19d851f148aa2932b87bf (diff) | |
download | syslinux-44bc900a31b8c83a4de92c45e0401ceaefe371e8.tar.gz |
memdisk: handle recursive INT 13h invocation
Some systems, e.g. a lot of Thinkpads, invoke INT 13h recursively from
within the stack itself. This is generally a bad idea as it re-runs
any INT 13h hooks (including the ones that DOS installs!), but it
should work. Keep a counter of recursive invocations and simply
bypass the whole system including the DL shift if the invocation is
recursive.
With this, MS-DOS boots on a Thinkpad T61. FreeDOS is still broken,
though, but apparently in a different manner...
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | memdisk/memdisk.inc | 64 |
1 files changed, 52 insertions, 12 deletions
diff --git a/memdisk/memdisk.inc b/memdisk/memdisk.inc index 00537a83..266b08ab 100644 --- a/memdisk/memdisk.inc +++ b/memdisk/memdisk.inc @@ -89,11 +89,13 @@ Pointers: dw Int13Start IretPtr equ Int13Start.iret Int13Start: + cmp word [cs:Recursive],0 + jne jmp_oldint13 + ; Swap stack mov [cs:Stack],esp + mov [cs:Stack+4],ss mov [cs:SavedAX],ax - mov ax,ss - mov [cs:Stack+4],ax mov ax,cs mov ss,ax mov sp,[cs:MyStack] @@ -106,24 +108,24 @@ Int13Start: js .nomatch ; If SF=0, we have a class match here ; 0x00 the sign bit for FD ; 0x80 the sign bit for HD - jz .our_drive ; If ZF=1, we have an exact match + jz our_drive ; If ZF=1, we have an exact match cmp dl,[cs:DriveNo] jb .nomatch ; Drive < Our drive dec dl ; Drive > Our drive, adjust drive # .nomatch: mov ax,[cs:SavedAX] + inc word [cs:Recursive] pushf call far [cs:OldInt13] pushf + dec word [cs:Recursive] push bp mov bp,sp cmp byte [cs:SavedAX+1],08h ; Get drive params function? - je .norestoredl + je .norestoredl ; DL = number of drives cmp byte [cs:SavedAX+1],15h ; Get disk type function? - jne .restoredl - test byte [bp+4],80h ; Hard disk? - jnz .norestoredl -.restoredl: ; DL should have number of drives + je .norestoredl ; CX:DX = size of device +.restoredl: mov dl,[bp+4] .norestoredl: push ax @@ -139,7 +141,10 @@ Int13Start: lss esp,[cs:Stack] .iret: iret -.our_drive: +jmp_oldint13: + jmp far [cs:OldInt13] + +our_drive: ; Set up standard entry frame push ds push es @@ -149,7 +154,7 @@ Int13Start: pushad mov bp,sp ; Point BP to the entry stack frame TRACER 'F' - ; Note: AH == P_AH here + ; Note: AX == P_AX here cmp ah,Int13FuncsCnt-1 ja Invalid_jump xor al,al ; AL = 0 is standard entry condition @@ -208,7 +213,7 @@ Reset: pop ds lss esp,[cs:Stack] ; Restore the stack and dl,80h ; Clear all but the type bit - jmp far [cs:OldInt13] + jmp jmp_oldint13 Invalid: @@ -224,11 +229,11 @@ GetDriveType: jz .floppy ; Hard disks only... inc bx ; Type = 03h +.floppy: mov dx,[DiskSize] ; Return the disk size in sectors mov P_DX,dx mov cx,[DiskSize+2] mov P_CX,cx -.floppy: mov P_AH,bl ; 02h floppy, 03h hard disk pop ax ; Drop return address xor ax,ax ; Success... @@ -792,6 +797,39 @@ debug_tracer: pushad popfd popad ret + +writehex2: pushad + pushfd + mov cx,2 + ror eax,4 + jmp writehex_common +writehex4: pushad + pushfd + mov cx,4 + ror eax,12 + jmp writehex_common +writehex8: pushad + pushfd + mov cx,8 + ror eax,28 +writehex_common: +.loop: push cx + push eax + and al,0Fh + cmp al,10 + jb .isdec + add al,'a'-'0'-10 +.isdec: add al,'0' + mov ah,0Eh + mov bx,7 + int 10h + pop eax + rol eax,4 + pop cx + loop .loop + popfd + popad + ret %endif section .data @@ -968,9 +1006,11 @@ EDD_DPT: %endif ; End patch area + alignb 4, db 0 Stack dd 0 ; Saved SS:ESP on invocation dw 0 SavedAX dw 0 ; AX saved on invocation +Recursive dw 0 ; Recursion counter alignb 4, db 0 ; We *MUST* end on a dword boundary |