[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