diff options
author | hpa <hpa> | 2005-09-20 17:03:17 +0000 |
---|---|---|
committer | hpa <hpa> | 2005-09-20 17:03:17 +0000 |
commit | 70d29bc5c0a20a6b825c3250f2f7c1bfb3e5764d (patch) | |
tree | f1894c9e211e559222d078e4cf276a0b8e9bb670 | |
parent | f3de199d6acc5c48d4624e73ac88076f333513b9 (diff) | |
download | syslinux-70d29bc5c0a20a6b825c3250f2f7c1bfb3e5764d.tar.gz |
EDD code, not enabled by default
-rw-r--r-- | memdisk/memdisk.asm | 147 |
1 files changed, 143 insertions, 4 deletions
diff --git a/memdisk/memdisk.asm b/memdisk/memdisk.asm index c59704da..e40be844 100644 --- a/memdisk/memdisk.asm +++ b/memdisk/memdisk.asm @@ -23,6 +23,12 @@ ; %define DEBUG_TRACERS ; Uncomment to get debugging tracers +%ifdef WITH_EDD +%define EDD 1 +%else +%define EDD 0 +%endif + %ifdef DEBUG_TRACERS %macro TRACER 1 @@ -318,8 +324,64 @@ GetParms: .notic: xor ax,ax ret - - ; Set up registers as for a "Read", and compares against disk size +; +; EDD functions -- only if enabled +; +%if EDD +EDDPresence: + cmp P_BX,55AAh + jne Invalid + mov P_BX,0AA55h ; EDD signature + mov P_AX,03000h ; EDD 3.0 + mov P_CX,0001h ; Fixed disk access subset + pop ax ; Drop return address + xor ax,ax ; Success + jmp DoneWeird ; Success, but AH != 0, sigh... + +EDDRead: + call edd_setup_regs + call bcopy + xor ax,ax + ret + +EDDWrite: + call edd_setup_regs + xchg esi,edi + call bcopy + xor ax,ax + ret + +EDDVerify: +EDDSeek: + call edd_setup_regs ; Just bounds checking + xor ax,ax + ret + +EDDGetParms: + mov es,P_DS + mov di,P_SI + mov cx,26 ; Length of our DPT + cmp [es:di],cx + jb .overrun + + ; This should be done by the installer... + mov eax,[DiskSize] + mov [si+16],eax + + mov si,EDD_DPT + rep movsb + + xor ax,ax + ret + +.overrun: + mov ax,0100h + ret +%endif ; EDD + + ; Set up registers as for a "Read", and compares against disk size. + ; WARNING: This fails immediately, even if we can transfer some + ; sectors. This isn't really the correct behaviour. setup_regs: ; Convert a CHS address in P_CX/P_DH into an LBA in eax @@ -359,13 +421,76 @@ setup_regs: add esi,[DiskBuf] ; Get address in high memory cmp eax,[DiskSize] ; Check the high mark against limit ja .overrun - shl ecx,SECTORSIZE_LG2-2 ; Convert count to 32-bit words + shl ecx,SECTORSIZE_LG2-2 ; Convert count to dwords ret .overrun: pop ax ; Drop setup_regs return address mov ax,0200h ; Missing address mark ret ; Return to Done + ; Set up registers as for an EDD Read, and compares against disk size. +%if EDD +edd_setup_regs: + mov si,P_SI ; DS:SI -> DAPA + mov es,P_DS + + mov dx,[es:si] + cmp dx,16 + jb .baddapa + + cmp dword [es:si+4],-1 + je .linear_address + + movzx esi,word [es:si+4] ; Offset + movzx edi,word [es:si+6] ; Segment + shl edi,4 + add esi,edi + + jmp .got_address + +.linear_address: + cmp dx,24 ; Must be large enough to hold linear address + jb .baddapa + + cmp dword [es:si+20],0 ; > 4 GB addresses not supported + jne .overrun + + mov esi,[es:si+16] + +.got_address: + cmp dword [es:si+12],0 ; LBA too large? + jne .overrun + + movzx ecx, word [es:si+2] ; Sectors to transfer + mov edi,[es:si+8] ; Starting sector + mov eax,edi + add eax,ecx + jc .overrun + cmp eax,[DiskSize] + ja .overrun + + shl ecx,SECTORSIZE_LG2-2 ; Convert to dwords + shl edi,SECTORSIZE_LG2 ; Convert to an offset + add edi,[DiskBuf] + ret + +.baddapa: + pop ax ; Drop setup_regs return address + mov ax,0100h ; Invalid command + ret + +.overrun: + and word [es:si+2],0 ; No sectors transferred + pop ax + mov ax,0200h + ret + +%endif ; EDD + + +; +; INT 15h intercept routines +; int15_e820: cmp edx,534D4150h ; "SMAP" jne near oldint15 @@ -628,7 +753,7 @@ Int13Funcs dw Reset ; 00h - RESET dw Invalid ; 14h dw GetDriveType ; 15h - GET DRIVE TYPE dw DetectChange ; 16h - DETECT DRIVE CHANGE -%if 0 +%if EDD dw Invalid ; 17h dw Invalid ; 18h dw Invalid ; 19h @@ -684,6 +809,20 @@ Int13Funcs dw Reset ; 00h - RESET Int13FuncsEnd equ $ Int13FuncsMax equ (Int13FuncsEnd-Int13Funcs) >> 1 +%if EDD +EDD_DPT: +.length dw 26 + ; Bit 0 - DMA boundaries handled transparently + ; Bit 3 - Device supports write verify +.info dw 0009h +.cylinders dd 0 ; No physical geometry +.heads dd 0 ; No physical geometry +.sectors dd 0 ; No physical geometry +.totalsize dd 0, 0 ; Total number of sectors +.bytespersec dw SECTORSIZE + +%endif + alignb 8, db 0 Shaker dw ShakerEnd-$ dd 0 ; Pointer to self |