[syslinux] MEMDISK without floppy drive

Robert Wruck robert at rw-it.net
Thu Aug 28 11:25:12 PDT 2003


ok, i received some requests for the patch, so here it is.

BE CAREFUL!
especially the EBD functions are not well tested and may cause damage to your system.

i modified the reset code so it only calls the original int13 if there are "real" drives to reset
(DriveCnt > 1), but there's no guarantee it works on your (every) system.

USE AT YOUR OWN RISK.


cheers,
robert

-------- cut here -------
--- memdisk.asm.orig	2003-04-16 07:23:31.000000000 +0200
+++ memdisk.asm	2003-08-28 01:08:16.000000000 +0200
@@ -161,17 +161,14 @@
 		lss esp,[cs:Stack]
 		iret
 
-Reset:
-		; Reset affects multiple drives, so we need to pass it on
-		TRACER 'R'
-		pop ax			; Drop return address
-		popad			; Restore all registers
-		pop es
-		pop ds
-		lss esp,[cs:Stack]	; Restore the stack
-		and dl,80h		; Clear all but the type bit
-		jmp far [cs:OldInt13]
 
+ExtCheck:				; ah=41
+		mov P_AH,20h	; EDD version 2.0
+		mov P_BX,0aa55h	; signature
+		mov P_CX,0001h	; functions 42-44,47,48
+		pop ax			; Drop return address
+		xor ax,ax		; Success...
+		jmp short DoneWeird	; But don't stick it into P_AX
 
 Invalid:
 		pop dx			; Drop return address
@@ -196,6 +193,24 @@
 		xor ax,ax		; Success...
 		jmp short DoneWeird	; But don't stick it into P_AX
 
+Reset:
+		; Reset affects multiple drives, so we need to pass it on
+		TRACER 'R'
+		cmp byte [DriveCnt],01h
+		ja .passon		; pass on if there are real drives to reset
+		xor ax,ax
+		ret
+
+.passon:
+		pop ax			; Drop return address
+		popad			; Restore all registers
+		pop es
+		pop ds
+		lss esp,[cs:Stack]	; Restore the stack
+		and dl,80h		; Clear all but the type bit
+		jmp far [cs:OldInt13]
+
+
 GetStatus:
 		xor ax,ax
 		mov es,ax
@@ -225,10 +240,55 @@
 InitWithParms:
 DetectChange:
 Seek:
+ExtSeek:
 success:
 		xor ax,ax		; Always successful
 		ret
 
+ExtRead:				; ah=42
+		call ext_setup_regs
+		jmp short do_copy
+
+ExtWrite:				; ah=43
+		call ext_setup_regs
+		xchg esi,edi		; Opposite direction of a Read!
+		jmp short do_copy
+
+ExtVerify:				; ah=44
+		call ext_setup_regs
+		xor ax,ax
+		ret
+
+ExtParms:				; ah=48
+		movzx esi,P_DS			; get linear structure address in esi
+		movzx eax,P_SI
+		shl esi,4
+		add esi,eax
+		cmp word [esi],001ah		; check structure size
+		jb .extparmserr
+		mov word [esi+02h],0016h	; removable drive with change line support
+		movzx eax,word [Cylinders]
+		mov [esi+04h],eax
+		movzx eax,word [Heads]
+		mov [esi+08h],eax
+		mov eax,[Sectors]
+		mov [esi+0ch],eax
+		mov eax,[DiskSize]
+		mov [esi+10h],eax
+		mov dword [esi+18h],SECTORSIZE
+		cmp word [esi],001eh
+		jb .extparmsend
+		xor eax,eax
+		not eax
+		mov dword [esi+1ah],eax	; EDD parameters not available
+.extparmsend:
+		xor eax,eax
+		mov [esi+14h],eax	; high 32 bits of disk size
+		ret
+.extparmserr:
+		mov ax,0700h
+		ret
+
 GetParms:
 		TRACER 'G'
 		mov dl,[DriveCnt]	; Cached data
@@ -296,6 +356,34 @@
 		mov ax,0200h		; Missing address mark
 		ret			; Return to Done
 
+		; set up registers for a "Read" using a "disk address packet" in P_DS:P_SI
+ext_setup_regs:
+		movzx esi,P_DS			; get linear structure address in esi
+		movzx edx,P_SI
+		shl esi,4
+		add esi,edx
+		cmp byte [esi],10h
+		jnz .overrun			; structure has wrong size
+		movzx ecx,word [esi+2]	; sector count
+		mov edi,[esi+4]			; transfer buffer
+		mov eax,[esi+8]			; LBA
+		xor edx,edx
+		; Now eax = LBA, edx = 0
+		;     ecx = sector count, edi = address to fetch to
+		
+		mov esi,eax
+		add eax,ecx		; LBA of final sector + 1
+		shl esi,SECTORSIZE_LG2	; LBA -> byte offset
+		add esi,[DiskBuf]	; Get address in high memory
+		cmp eax,[DiskSize]	; Check the high mark against limit
+		ja .overrun
+		shl ecx,SECTORSIZE_LG2-1 ; Convert count to 16-bit words
+		ret
+
+.overrun:	pop ax			; Drop setup_regs return address
+		mov ax,0200h		; Missing address mark
+		ret			; Return to Done
+
 int15_e820:
 		cmp edx,534D4150h	; "SMAP"
 		jne near oldint15
@@ -466,6 +554,56 @@
 		dw Invalid		; 14h
 		dw GetDriveType		; 15h - GET DRIVE TYPE
 		dw DetectChange		; 16h - DETECT DRIVE CHANGE
+		dw Invalid		; 17h
+		dw Invalid		; 18h
+		dw Invalid		; 19h
+		dw Invalid		; 1ah
+		dw Invalid		; 1bh
+		dw Invalid		; 1ch
+		dw Invalid		; 1dh
+		dw Invalid		; 1eh
+		dw Invalid		; 1fh
+		dw Invalid		; 20h
+		dw Invalid		; 21h
+		dw Invalid		; 22h
+		dw Invalid		; 23h
+		dw Invalid		; 24h
+		dw Invalid		; 25h
+		dw Invalid		; 26h
+		dw Invalid		; 27h
+		dw Invalid		; 28h
+		dw Invalid		; 29h
+		dw Invalid		; 2ah
+		dw Invalid		; 2bh
+		dw Invalid		; 2ch
+		dw Invalid		; 2dh
+		dw Invalid		; 2eh
+		dw Invalid		; 2fh
+		dw Invalid		; 30h
+		dw Invalid		; 31h
+		dw Invalid		; 32h
+		dw Invalid		; 33h
+		dw Invalid		; 34h
+		dw Invalid		; 35h
+		dw Invalid		; 36h
+		dw Invalid		; 37h
+		dw Invalid		; 38h
+		dw Invalid		; 39h
+		dw Invalid		; 3ah
+		dw Invalid		; 3bh
+		dw Invalid		; 3ch
+		dw Invalid		; 3dh
+		dw Invalid		; 3eh
+		dw Invalid		; 3fh
+		dw Invalid		; 40h
+		dw ExtCheck		; 41h ; check for extended functions
+		dw ExtRead		; 42h ; extended read
+		dw ExtWrite		; 43h ; extended write
+		dw ExtVerify	; 44h ; extended verify
+		dw Invalid		; 45h
+		dw Invalid		; 46h
+		dw ExtSeek		; 47h ; extended seek
+		dw ExtParms		; 48h ; extended parameters
 Int13FuncsEnd	equ $
 Int13FuncsMax	equ (Int13FuncsEnd-Int13Funcs) >> 1
 
-------- cut here -------




More information about the Syslinux mailing list