summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-07-30 11:24:25 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-07-30 11:24:25 -0700
commit44bc900a31b8c83a4de92c45e0401ceaefe371e8 (patch)
tree7a49f7cb47d6b7afeb623bbfcba107411bb83de7
parent3cdc491e358508621ce19d851f148aa2932b87bf (diff)
downloadsyslinux-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.inc64
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