summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux-4.02/dosutil
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux-4.02/dosutil')
-rw-r--r--contrib/syslinux-4.02/dosutil/.gitignore1
-rw-r--r--contrib/syslinux-4.02/dosutil/Makefile60
-rw-r--r--contrib/syslinux-4.02/dosutil/README10
-rw-r--r--contrib/syslinux-4.02/dosutil/copybs.asm271
-rw-r--r--contrib/syslinux-4.02/dosutil/eltorito.asm1099
-rw-r--r--contrib/syslinux-4.02/dosutil/eltorito.txt50
-rw-r--r--contrib/syslinux-4.02/dosutil/mdiskchk.c357
-rw-r--r--contrib/syslinux-4.02/dosutil/mdiskchk.combin0 -> 8106 bytes
8 files changed, 1848 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/dosutil/.gitignore b/contrib/syslinux-4.02/dosutil/.gitignore
new file mode 100644
index 0000000..0aec5f2
--- /dev/null
+++ b/contrib/syslinux-4.02/dosutil/.gitignore
@@ -0,0 +1 @@
+!mdiskchk.com
diff --git a/contrib/syslinux-4.02/dosutil/Makefile b/contrib/syslinux-4.02/dosutil/Makefile
new file mode 100644
index 0000000..fc10ff9
--- /dev/null
+++ b/contrib/syslinux-4.02/dosutil/Makefile
@@ -0,0 +1,60 @@
+#
+# OpenWatcom compile and link utility
+#
+topdir = ..
+include $(topdir)/MCONFIG
+
+WCL = wcl
+WCLOPT = -6 -osx -mt -bt=DOS -l=COM
+
+UPX = upx
+
+NASM = nasm
+NASMOPT = -O9999
+
+WCTARGETS = mdiskchk.com
+NSTARGETS = eltorito.sys copybs.com
+TARGETS = $(WCTARGETS) $(NSTARGETS)
+
+%.obj: %.c
+ $(WCL) $(WCLOPT) -c -fo=$@ $<
+
+%.com: %.obj
+ $(WCL) $(WCLOPT) -fe=$@ $<
+ $(UPX) --ultra-brute --lzma $@ || \
+ $(UPX) --ultra-brute $@ || \
+ true
+ rm -f $*.0*
+ chmod a-x $@
+
+%.sys: %.asm
+ $(NASM) $(NASMOPT) -f bin -o $@ -l $*.lst $<
+ $(UPX) --ultra-brute --lzma $@ || \
+ $(UPX) --ultra-brute $@ || \
+ true
+ rm -f $*.0*
+ chmod a-x $@
+
+%.com: %.asm
+ $(NASM) $(NASMOPT) -f bin -o $@ -l $*.lst $<
+ $(UPX) --ultra-brute --lzma $@ || \
+ $(UPX) --ultra-brute $@ || \
+ true
+ rm -f $*.0*
+ chmod a-x $@
+
+all: $(TARGETS)
+
+tidy dist:
+ -rm -f *.obj *.lst *.o *.0*
+
+clean: tidy
+
+spotless: clean
+ -rm -f $(NSTARGETS) *~
+
+installer: all
+
+install: installer
+ mkdir -m 755 -p $(INSTALLROOT)$(AUXDIR)/dosutil
+ install -m 644 $(TARGETS) $(INSTALLROOT)$(AUXDIR)/dosutil
diff --git a/contrib/syslinux-4.02/dosutil/README b/contrib/syslinux-4.02/dosutil/README
new file mode 100644
index 0000000..0b7b2a9
--- /dev/null
+++ b/contrib/syslinux-4.02/dosutil/README
@@ -0,0 +1,10 @@
+This directory contains utilities for use under DOS.
+Although not part of Syslinux per se, they might be useful with MEMDISK.
+
+eltorito.sys - Generic El Torito CD-ROM driver
+ Written by Gary Tong and Bart Lagerweij.
+ Ported to NASM by H. Peter Anvin.
+
+mdiskchk.com - Simple program to query for the existence of a
+ MEMDISK and display parameters.
+
diff --git a/contrib/syslinux-4.02/dosutil/copybs.asm b/contrib/syslinux-4.02/dosutil/copybs.asm
new file mode 100644
index 0000000..2640714
--- /dev/null
+++ b/contrib/syslinux-4.02/dosutil/copybs.asm
@@ -0,0 +1,271 @@
+; -*- fundamental -*- (asm-mode sucks)
+; -----------------------------------------------------------------------
+;
+; Copyright 1998-2008 H. Peter Anvin - All Rights Reserved
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+; Boston MA 02111-1307, USA; either version 2 of the License, or
+; (at your option) any later version; incorporated herein by reference.
+;
+; -----------------------------------------------------------------------
+
+;
+; copybs.asm
+;
+; Small DOS program to copy the boot sector from a drive
+; to a file
+;
+; Usage: copybs <drive>: <file>
+;
+
+ absolute 0
+pspInt20: resw 1
+pspNextParagraph: resw 1
+ resb 1 ; reserved
+pspDispatcher: resb 5
+pspTerminateVector: resd 1
+pspControlCVector: resd 1
+pspCritErrorVector: resd 1
+ resw 11 ; reserved
+pspEnvironment: resw 1
+ resw 23 ; reserved
+pspFCB_1: resb 16
+pspFCB_2: resb 16
+ resd 1 ; reserved
+pspCommandLen: resb 1
+pspCommandArg: resb 127
+
+ section .text
+ org 100h ; .COM format
+_start:
+ mov ax,3000h ; Get DOS version
+ int 21h
+ xchg al,ah
+ mov [DOSVersion],ax
+ cmp ax,0200h ; DOS 2.00 minimum
+ jae dosver_ok
+ mov dx,msg_ancient_err
+ jmp die
+
+ section .bss
+ alignb 2
+DOSVersion: resw 1
+
+ section .text
+;
+; Scan command line for a drive letter followed by a colon
+;
+dosver_ok:
+ xor cx,cx
+ mov si,pspCommandArg
+ mov cl,[pspCommandLen]
+
+cmdscan1: jcxz bad_usage ; End of command line?
+ lodsb ; Load character
+ dec cx
+ cmp al,' ' ; White space
+ jbe cmdscan1
+ or al,020h ; -> lower case
+ cmp al,'a' ; Check for letter
+ jb bad_usage
+ cmp al,'z'
+ ja bad_usage
+ sub al,'a' ; Convert to zero-based index
+ mov [DriveNo],al ; Save away drive index
+
+ section .bss
+DriveNo: resb 1
+
+ section .text
+;
+; Got the leading letter, now the next character must be a colon
+;
+got_letter: jcxz bad_usage
+ lodsb
+ dec cx
+ cmp al,':'
+ jne bad_usage
+;
+; Got the colon; now we should have at least one whitespace
+; followed by a filename
+;
+got_colon: jcxz bad_usage
+ lodsb
+ dec cx
+ cmp al,' '
+ ja bad_usage
+
+skipspace: jcxz bad_usage
+ lodsb
+ dec cx
+ cmp al,' '
+ jbe skipspace
+
+ mov di,FileName
+copyfile: stosb
+ jcxz got_cmdline
+ lodsb
+ dec cx
+ cmp al,' '
+ ja copyfile
+ jmp short got_cmdline
+
+;
+; We end up here if the command line doesn't parse
+;
+bad_usage: mov dx,msg_unfair
+ jmp die
+
+ section .data
+msg_unfair: db 'Usage: copybs <drive>: <filename>', 0Dh, 0Ah, '$'
+
+ section .bss
+ alignb 4
+FileName resb 256
+
+;
+; Parsed the command line OK. Get device parameter block to get the
+; sector size.
+;
+ struc DPB
+dpbDrive: resb 1
+dpbUnit: resb 1
+dpbSectorSize: resw 1
+dpbClusterMask: resb 1
+dpbClusterShift: resb 1
+dpbFirstFAT: resw 1
+dpbFATCount: resb 1
+dpbRootEntries: resw 1
+dpbFirstSector: resw 1
+dpbMaxCluster: resw 1
+dpbFATSize: resw 1
+dpbDirSector: resw 1
+dpbDriverAddr: resd 1
+dpbMedia: resb 1
+dpbFirstAccess: resb 1
+dpbNextDPB: resd 1
+dpbNextFree: resw 1
+dpbFreeCnt: resw 1
+ endstruc
+
+ section .bss
+ alignb 2
+SectorSize resw 1
+
+ section .text
+got_cmdline:
+ xor al,al ; Zero-terminate filename
+ stosb
+
+ mov dl,[DriveNo]
+ inc dl ; 1-based
+ mov ah,32h
+ int 21h ; Get Drive Parameter Block
+
+ and al,al
+ jnz filesystem_error
+
+ mov dx,[bx+dpbSectorSize] ; Save sector size
+;
+; Read the boot sector.
+;
+ section .data
+ align 4, db 0
+DISKIO equ $
+diStartSector: dd 0 ; Absolute sector 0
+diSectors: dw 1 ; One sector
+diBuffer: dw SectorBuffer ; Buffer offset
+ dw 0 ; Buffer segment
+
+ section .text
+read_bootsect:
+ mov ax,cs ; Set DS <- CS
+ mov ds,ax
+
+ mov [SectorSize],dx ; Saved sector size from above
+
+ cmp word [DOSVersion],0400h ; DOS 4.00 has a new interface
+ jae .new
+.old:
+ mov bx,SectorBuffer
+ mov cx,1 ; One sector
+ jmp short .common
+.new:
+ mov [diBuffer+2],ax ; == DS
+ mov bx,DISKIO
+ mov cx,-1
+.common:
+ xor dx,dx ; Absolute sector 0
+ mov al,[DriveNo]
+ int 25h ; DOS absolute disk read
+ pop ax ; Remove flags from stack
+ jc disk_read_error
+
+;
+; Open the file and write the boot sector to the file.
+;
+ mov dx,FileName
+ mov cx,0020h ; Attribute = ARCHIVE
+ mov ah,3Ch ; Create file
+ int 21h
+ jc file_write_error
+
+ mov bx,ax
+ push ax ; Handle
+
+ mov cx,[SectorSize]
+ mov dx,SectorBuffer
+ mov ah,40h ; Write file
+ int 21h
+ jc file_write_error
+ cmp ax,[SectorSize]
+ jne file_write_error
+
+ pop bx ; Handle
+ mov ah,3Eh ; Close file
+ int 21h
+ jc file_write_error
+;
+; We're done!
+;
+ mov ax,4C00h ; exit(0)
+ int 21h
+
+;
+; Error routine jump
+;
+filesystem_error:
+ mov dx,msg_filesystem_err
+ jmp short die
+disk_read_error:
+ mov dx,msg_read_err
+ jmp short die
+file_write_error:
+ mov dx,msg_write_err
+die:
+ push cs
+ pop ds
+ push dx
+ mov dx,msg_error
+ mov ah,09h
+ int 21h
+ pop dx
+
+ mov ah,09h ; Write string
+ int 21h
+
+ mov ax,4C01h ; Exit error status
+ int 21h
+
+ section .data
+msg_error: db 'ERROR: $'
+msg_ancient_err: db 'DOS version 2.00 or later required', 0Dh, 0Ah, '$'
+msg_filesystem_err: db 'Filesystem not found on disk', 0Dh, 0Ah, '$'
+msg_read_err: db 'Boot sector read failed', 0Dh, 0Ah, '$'
+msg_write_err: db 'File write failed', 0Dh, 0Ah, '$'
+
+ section .bss
+ alignb 4
+SectorBuffer: resb 4096
diff --git a/contrib/syslinux-4.02/dosutil/eltorito.asm b/contrib/syslinux-4.02/dosutil/eltorito.asm
new file mode 100644
index 0000000..d6b6b50
--- /dev/null
+++ b/contrib/syslinux-4.02/dosutil/eltorito.asm
@@ -0,0 +1,1099 @@
+
+;-----------------------------------------------------------------------------
+; ElTorito.asm
+;
+; El Torito Bootable CD-ROM driver which does not reset the CD-ROM drive upon
+; loading, but instead accesses the drive through BIOS system calls
+;
+; MIT License
+;
+; (c) 2000 by Gary Tong
+; (c) 2001-2009 by Bart Lagerweij
+;
+; Permission is hereby granted, free of charge, to any person obtaining a copy
+; of this software and associated documentation files (the "Software"), to deal
+; in the Software without restriction, including without limitation the rights
+; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+; copies of the Software, and to permit persons to whom the Software is
+; furnished to do so, subject to the following conditions:
+;
+; The above copyright notice and this permission notice shall be included in
+; all copies or substantial portions of the Software.
+;
+; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+; THE SOFTWARE.
+;
+;-----------------------------------------------------------------------------
+
+; To assemble and link, use these commands with NASM 2.x:
+; nasm -Ox -f bin -o eltorito.sys eltorito.asm
+
+; To enable Trace markers uncomment the line below
+; DEBUG_TRACERS=1
+
+; To enable debug info uncomment the line below
+; DEBUG=1
+
+%ifdef DEBUG_TRACERS
+ %macro TRACER 1
+ call debug_tracer
+ db %1
+ %endmacro
+%else
+ %macro TRACER 1
+ %endmacro
+%endif ; DEBUG_TRACERS
+
+%define Ver '1.5'
+%define CR 0DH, 0Ah
+RPolyH equ 0EDB8h
+RPolyL equ 08320h
+
+ section .text align=16
+ org 0
+
+;=============================================================================
+
+Cdrom:
+
+NextDriver dd -1 ;-+
+Attributes dw 0C800h ; |
+Pointers dw Strategy ; |
+ dw Commands ; | MSCDEX requires this
+DeviceName db 'ELTORITO' ; | data in these locations
+ dw 0 ; |
+DriveLetter db 0 ; |
+NumUnitsSupp db 1 ;-+
+
+DriverName db 'El-Torito CD-ROM Device Driver',0
+ align 4, db 0
+ReqHdrLoc dd 0
+XferAddr dd 0
+Checksum dd -1
+DriveNumber db 0
+ReadBytes db 0 ;0 --> 2048 bytes/sector
+ ;1 --> 1024 bytes/sector
+ ;2 --> 512 bytes/sector
+
+Routines dw Init ;Init ;0
+ dw Unsupported ;MediaCheck ;1
+ dw Unsupported ;BuildBPB ;2
+ dw IoctlInput ;IoctlInput ;3
+ dw Unsupported ;Input ;4
+ dw Unsupported ;NonDesInput ;5
+ dw Unsupported ;InputStatus ;6
+ dw Unsupported ;InputFlush ;7
+ dw Unsupported ;Output ;8
+ dw Unsupported ;OutputVerify ;9
+ dw Unsupported ;OutputStatus ;10
+ dw Unsupported ;OutputFlush ;11
+ dw IoctlOutput ;IoctlOutput ;12
+ dw DoNothing ;DeviceOpen ;13
+ dw DoNothing ;DeviceClose ;14
+ dw ReadL ;ReadL ;128
+
+IoctlICtrl dw Raddr ;Raddr ;0
+ dw Unsupported ;LocHead ;1
+ dw Unsupported ;(Reserved) ;2
+ dw Unsupported ;ErrStat ;3
+ dw Unsupported ;AudInfo ;4
+ dw DrvBytes ;DrvBytes ;5
+ dw DevStat ;DevStat ;6
+ dw SectSize ;SectSize ;7
+ dw VolSize ;VolSize ;8
+ dw MedChng ;MedChng ;9
+
+SpecPkt times 19 db 0 ; offset 77h in 1.4
+ times 13 db 0 ; unknown extra 00s in 1.4
+
+Greeting db 'El-Torito Bootable CD-ROM Driver for Dos v',Ver,', http://www.nu2.nu/eltorito/',CR
+ db ' (c) 2000 by Gary Tong',CR
+ db ' (c) 2001-2002 by Bart Lagerweij',CR,0
+DblSpace db ' ',0
+
+;=============================================================================
+
+Strategy:
+
+ mov word [cs:ReqHdrLoc],bx
+ mov word [cs:ReqHdrLoc+2],es
+ retf
+
+
+;=============================================================================
+
+Commands:
+
+ push ax
+ push bx
+ push cx
+ push dx
+ push si
+ push di
+ push bp
+; pushad
+ push ds
+ push es
+ TRACER 'C'
+
+ cld ;Clear direction
+ sti ;Enable interrupts
+
+ mov ax, cs ;ds=cs
+ mov ds, ax
+
+ les bx,[ReqHdrLoc] ;seg:offset ptr into es:bx
+ xor ax,ax
+ mov al,[es:bx+2] ;Get Command code
+%ifdef DEBUG
+ call print_hex8
+%endif
+ cmp al,15
+ jb Mult2 ;If 0-14
+ cmp al,128
+ jb UnknownCmd ;If 15-127
+ cmp al,129
+ jb ShiftDown ;If 128
+UnknownCmd: mov al,121 ;8 = Unsupported (Reserved)
+ShiftDown: sub al,113 ;128 --> 15, 121 --> 8
+Mult2: shl al,1 ;Convert into offset (*2)
+ mov di,Routines
+ add di,ax
+ call word [di] ;Execute desired command
+ or ax,100h ;Set Return Status's Done bit
+ lds bx,[ReqHdrLoc] ;seg:offset ptr into ds:bx
+ mov [bx+3],ax ;Save Status
+
+%ifdef DEBUG
+ cmp byte [cs:buffer+2048], 96h
+ je buffer_ok
+ mov al, '!'
+ call print_char
+ jmp $
+buffer_ok:
+%endif
+
+ TRACER 'c'
+ pop es
+ pop ds
+; popad
+ pop bp
+ pop di
+ pop si
+ pop dx
+ pop cx
+ pop bx
+ pop ax
+ retf
+
+
+;=============================================================================
+
+Unsupported: ;Unsupported Command
+
+ mov ax,8003h ;Set Status Error bit,
+ TRACER 'U'
+ TRACER 'C'
+ retn ; Error 3 = Unknown Command
+
+
+;=============================================================================
+
+IoctlInput: ;IOCTL Input Routine
+
+ mov di,[es:bx+14] ;es:bx --> Request Header
+ mov es,[es:bx+16] ;Get Xfer Address into es:di
+ xor ax,ax ;Get Control Block Code
+ mov al,[es:di]
+%ifdef DEBUG
+ TRACER 'I'
+ TRACER 'O'
+ call print_hex8
+%endif
+ cmp al,10
+ jb UnkIoctlI ;If 0-9
+ mov al,2 ;Map to Unsupported
+UnkIoctlI: shl al,1 ;Convert into offset (*2)
+ mov si,IoctlICtrl
+ add si,ax
+ call word [si] ;Execute desired command
+ retn
+
+
+;=============================================================================
+
+Raddr: ;Return Device Header Address
+
+ TRACER 'A'
+ mov word [es:di+1],0
+ mov [es:di+3],cs
+ xor ax, ax ;Set Return Status = success
+ TRACER 'a'
+ retn
+
+
+;=============================================================================
+
+DrvBytes: ;Read Drive Bytes
+
+ TRACER 'B'
+ push di ;Save original Xfer Addr
+ add di,2 ;Point to 1st dest byte
+ mov si,Greeting ;Point to Greeting
+DrvB: movsb ;Copy over a byte
+ cmp byte [si],13 ;Is next char a CR?
+ jne DrvB ;Loop if not
+
+ sub di,2 ;Get #bytes copied into ax
+ mov ax,di
+ pop di ;Retrieve original Xfer Addr
+ sub ax,di
+ mov byte [es:di+1],al ;and save it
+ mov ax,0 ;Set Return Status = success
+ TRACER 'b'
+ retn
+
+
+;=============================================================================
+
+DevStat: ;Return Device Status
+
+ TRACER 'D'
+ mov word [es:di+1],202h ;Door closed
+ mov word [es:di+3],0 ;Door unlocked
+ ;Supports only cooked reading
+ ;Read only
+ ;Data read only
+ ;No interleaving
+ ;No prefetching
+ ;No audio channel manipulation
+ ;Supports both HSG and Redbook
+ ; addressing modes
+
+ xor ax, ax ;Set Return Status = success
+ TRACER 'd'
+ retn
+
+
+;=============================================================================
+
+SectSize: ;Return Sector Size
+
+ TRACER 'S'
+ mov word [es:di+2],2048
+ mov ax,0 ;Set Return Status = success
+ TRACER 's'
+ retn
+
+
+;=============================================================================
+
+VolSize: ;Return Volume Size
+
+ TRACER 'V'
+ call PriVolDesc ;Get and Check Primary Volume
+ ; Descriptor
+ mov ax,800Fh ;Assume Invalid Disk Change
+ jc VolExit ;If Read Failure
+
+ mov ax,word [Buffer+80] ;Read Successful
+ mov word [es:di+1],ax ;Copy over Volume Size
+ mov ax,word [Buffer+82]
+ mov word [es:di+3],ax
+ mov ax,0 ;Set Return Status = success
+VolExit:
+ TRACER 'v'
+ retn
+
+
+;=============================================================================
+
+MedChng: ;Return Media Changed Status
+
+ TRACER 'M'
+ call PriVolDesc ;Get and Check Primary Volume
+ ; Descriptor
+ mov byte [es:di+1],-1 ;Assume Media Changed
+ mov ax,800Fh ; and Invalid Disk Change
+ jc MedExit ;If Media Changed or Bad
+
+ mov byte [es:di+1],1 ;Media has not changed
+ mov ax,0 ;Set Return Status = success
+MedExit:
+ TRACER 'm'
+ retn
+
+
+;=============================================================================
+
+PriVolDesc: ;Get and Check Primary Volume
+ ; Descriptor
+ TRACER 'P'
+ mov ax,cs ;Set ds:si --> SpecPkt
+ mov ds,ax
+
+ mov cx, 5
+PriVolAgain:
+ mov byte [SpecPkt],16 ;SpecPkt Size
+ mov byte [SpecPkt+1],0 ;Reserved
+ mov word [SpecPkt+2],1 ;Transfer one 2048-byte sector
+ push cx
+ mov cl,byte [ReadBytes] ;Multiply by 4 if reading 512
+ shl word [SpecPkt+2],cl ; bytes at a time
+ pop cx
+ mov word [SpecPkt+6],cs ;Into our Buffer
+ mov word [SpecPkt+4], Buffer
+ mov word [SpecPkt+8],16 ;From CD Sector 16
+ mov word [SpecPkt+10],0
+ mov word [SpecPkt+12],0
+ mov word [SpecPkt+14],0
+
+ mov si, SpecPkt
+ mov dl, [DriveNumber]
+ mov ah, 42h ;Extended Read
+ int 13h
+ jnc PriVolPass ;If success
+
+; TRACER '1'
+ ; read error
+ loop PriVolAgain
+
+ TRACER '2'
+ ; read retries exhausted
+ ; flow into below
+ jmp PriReadErr
+
+PriVolPass:
+ mov si,Buffer ;Point input to Buffer
+ mov ax,-1 ;Init Checksum registers
+ mov bx,ax ; bx,ax = 0FFFFFFFFh
+ jc PriNew ;If Read Failure
+
+ push di ;Read Successful,
+ ; so Calculate Checksum
+ mov di,1024 ;Init Word counter
+PriWord: mov dx,[cs:si] ;Grab next word from buffer
+ mov cx,16 ;Init bit counter
+PriBit: shr dx,1 ;Shift everything right 1 bit
+ rcr bx,1
+ rcr ax,1
+ jnc NoMult ;If a zero shifted out
+
+ xor bx,RPolyH ;A one shifted out, so XOR
+ xor ax,RPolyL ; Checksum with RPoly
+NoMult:
+ loop PriBit
+
+ add si,2 ;Inc Word Pointer
+ dec di
+ ja PriWord
+ TRACER '3'
+
+ pop di ;Checksum calculation complete
+ cmp bx,[Checksum+2] ;Has Checksum changed?
+ jne PriNew ;If Checksum Changed
+
+ cmp ax,[Checksum]
+ jne PriNew ;If Checksum Changed
+
+ clc ;Checksum not changed, CF=0
+ mov ax,0 ;Status = success
+ jmp PriOld
+
+PriReadErr:
+ mov WORD [Checksum+2],bx ;Save New Checksum
+ mov [Checksum],ax ; or 0FFFFFFFFh if bad read
+ stc ;Checksum change, CF=1
+ mov ax, 800bh ;Status = read fault
+ jmp PriOld
+
+PriNew: mov WORD [Checksum+2],bx ;Save New Checksum
+ mov [Checksum],ax ; or 0FFFFFFFFh if bad read
+ stc ;Checksum Changed, CF=1
+ mov ax,800Fh ;Status = Invalid Media Change
+PriOld:
+ TRACER 'p'
+ retn
+
+
+;=============================================================================
+
+IoctlOutput: ;IOCTL Output Routine
+
+ TRACER 'O'
+ mov di,[es:bx+14] ;es:bx --> Request Header
+ mov es,[es:bx+16] ;Get Xfer Address into es:di
+ xor ax,ax ;Get Control Block Code
+ mov al,[es:di]
+ cmp al,2
+ jne UnkIoctlO ;If not 2 (ResetDrv)
+ call DoNothing ;Reset Drive
+ jmp IoctlODone
+UnkIoctlO:
+ call Unsupported ;Unsupported command
+IoctlODone:
+ TRACER 'o'
+ retn
+
+
+;=============================================================================
+
+DoNothing: ;Do Nothing Command
+
+ mov ax,0 ;Set Return Status = success
+ retn
+
+
+;=============================================================================
+
+ReadL: ;Read Long Command
+
+ TRACER 'R'
+ mov ax,cs ;Set ds=cs
+ mov ds,ax
+ ;es:bx --> Request Header
+ cmp byte [es:bx+24],0 ;Check Data Read Mode
+ jne ReadLErr ;If Cooked Mode
+
+ cmp byte [es:bx+13],2 ;Check Addressing Mode
+ jb ReadLOK ;If HSG or Redbook Mode
+
+ReadLErr:
+ TRACER '8'
+ mov ax,8003h ;Set Return Status = Unknown
+ jmp ReadLExit ; Command Error and exit
+
+ReadLOK:
+ mov ax,[es:bx+20] ;Get Starting Sector Number,
+ mov dx,[es:bx+22] ; Assume HSG Addressing Mode
+ cmp byte [es:bx+13],0 ;Check Addressing Mode again
+ je ReadLHSG ;If HSG Addressing Mode
+
+ TRACER '7'
+ ;Using Redbook Addressing Mode. Convert to HSG format
+ mov al,dl ;Get Minutes
+ mov dl,60
+ mul dl ;ax = Minutes * 60
+ add al,byte [es:bx+21] ;Add in Seconds
+ adc ah,0
+ mov dx,75 ;dx:ax =
+ mul dx ; ((Min * 60) + Sec) * 75
+ add al,byte [es:bx+20] ;Add in Frames
+ adc ah,0
+ adc dx,0
+ sub ax,150 ;Subtract 2-Second offset
+ sbb dx,0 ;dx:ax = HSG Starting Sector
+
+ReadLHSG:
+ mov word [SpecPkt+8], ax ;Store Starting
+ mov word [SpecPkt+10], dx ; Sector Number
+ mov word [SpecPkt+12], 0 ; (HSG Format)
+ mov word [SpecPkt+14], 0
+
+ mov ax,[es:bx+14] ;Get Transfer Address
+ mov word [SpecPkt+4],ax
+ mov ax,[es:bx+16]
+ mov word [SpecPkt+6],ax
+
+ mov byte [SpecPkt],16 ;Size of Disk Address Packet
+ mov byte [SpecPkt+1],0 ;Reserved
+
+ mov cx, 5
+ReadLAgain:
+ mov ax,[es:bx+18] ;Get number of sectors to read
+ mov word [SpecPkt+2],ax
+ cmp ax, 3FFFh ;Too large?
+ ja ReadLBad ;If yes
+
+ push cx
+ mov cl,byte [ReadBytes] ;Multiply by 4 if reading 512
+ shl word [SpecPkt+2],cl ; bytes at a time
+ pop cx
+
+%ifdef DEBUG
+ push ax
+ push cx
+ push si
+ mov cx, 16
+ mov si,SpecPkt
+ReadDump: mov al, ' '
+ call print_char
+ mov al, byte [si] ;Hexdump a SpecPkt byte
+ call print_hex8
+ inc si ;Point to next byte
+ loop ReadDump
+ pop si
+ pop cx
+ pop ax
+%endif
+ mov si,SpecPkt
+ mov dl,[DriveNumber]
+ mov ah,42h ;Extended Read
+ int 13h
+ jnc ReadLGd ;If success
+
+;hang:
+; jmp hang
+; TRACER '1'
+ loop ReadLAgain
+ TRACER '2'
+ jmp short ReadLBad
+ReadLGd:
+ TRACER '3'
+ xor ax, ax ;Status 0 = success
+ jmp short ReadLExit
+
+ReadLBad:
+ TRACER '9'
+ mov ax, 800Bh ;Set Read Fault Error
+ ; flow into ReadLExit
+ReadLExit:
+ TRACER 'r'
+ retn
+
+
+
+%ifdef DEBUG_TRACERS
+debug_tracer: pushad
+ pushfd
+
+ mov al, '['
+ mov ah,0Eh ;BIOS video teletype output
+ xor bh, bh
+ int 10h ;Print it
+
+ mov bp,sp
+ mov bx,[bp+9*4] ; Get return address
+ mov al,[cs:bx] ; Get data byte
+ inc word [bp+9*4] ; Return to after data byte
+
+ mov ah,0Eh ;BIOS video teletype output
+ xor bh, bh
+ int 10h ;Print it
+
+ mov al, ']'
+ mov ah,0Eh ;BIOS video teletype output
+ xor bh, bh
+ int 10h ;Print it
+
+ popfd
+ popad
+ retn
+%endif
+
+;-----------------------------------------------------------------------------
+; PRINT_HEX4
+;-----------------------------------------------------------------------------
+; print a 4 bits integer in hex
+;
+; Input:
+; AL - 4 bits integer to print (low)
+;
+; Output: None
+;
+; Registers destroyed: None
+;
+print_hex4:
+
+ push ax
+ and al, 0fh ; we only need the first nibble
+ cmp al, 10
+ jae hex_A_F
+ add al, '0'
+ jmp hex_0_9
+hex_A_F:
+ add al, 'A'-10
+hex_0_9:
+ call print_char
+ pop ax
+ retn
+
+
+;-----------------------------------------------------------------------------
+; print_hex8
+;-----------------------------------------------------------------------------
+; print a 8 bits integer in hex
+;
+; Input:
+; AL - 8 bits integer to print
+;
+; Output: None
+;
+; Registers destroyed: None
+;
+print_hex8:
+
+ push ax
+ push bx
+
+ mov ah, al
+ shr al, 4
+ call print_hex4
+
+ mov al, ah
+ and al, 0fh
+ call print_hex4
+
+ pop bx
+ pop ax
+ retn
+
+
+;=============================================================================
+; print_hex16 - print a 16 bits integer in hex
+;
+; Input:
+; AX - 16 bits integer to print
+;
+; Output: None
+;
+; Registers destroyed: None
+;=============================================================================
+print_hex16:
+
+ push ax
+ push bx
+ push cx
+
+ mov cx, 4
+print_hex16_loop:
+ rol ax, 4
+ call print_hex4
+ loop print_hex16_loop
+
+ pop cx
+ pop bx
+ pop ax
+ retn
+
+;=============================================================================
+; print_hex32 - print a 32 bits integer in hex
+;
+; Input:
+; EAX - 32 bits integer to print
+;
+; Output: None
+;
+; Registers destroyed: None
+;=============================================================================
+print_hex32:
+
+ push eax
+ push bx
+ push cx
+
+ mov cx, 8
+print_hex32_loop:
+ rol eax, 4
+ call print_hex4
+ loop print_hex32_loop
+
+ pop cx
+ pop bx
+ pop eax
+ retn
+
+;=============================================================================
+; print_string - print string at current cursor location
+;
+; Input:
+; DS:SI - ASCIIZ string to print
+;
+; Output: None
+;
+; Registers destroyed: None
+;=============================================================================
+print_string:
+ push ax
+ push si
+
+print_string_again:
+ mov al, [si]
+ or al, al
+ jz print_string_exit
+ call print_char
+ inc si
+ jmp print_string_again
+
+print_string_exit:
+ pop si
+ pop ax
+ retn
+
+;-----------------------------------------------------------------------------
+; PRINT_CHAR
+;-----------------------------------------------------------------------------
+; Print's a character at current cursor position
+;
+; Input:
+; AL - Character to print
+;
+; Output: None
+;
+; Registers destroyed: None
+;
+print_char:
+
+ push ax
+ push bx
+
+ mov ah,0Eh ;BIOS video teletype output
+ xor bh, bh
+ int 10h ;Print it
+
+print_char_exit:
+ pop bx
+ pop ax
+ retn
+
+
+;=============================================================================
+
+;This space is used as a 2048-byte read buffer plus one test byte.
+;The 96h data is used for testing the number of bytes returned by an Extended
+; CD-ROM sector read
+
+ align 16, db 0
+Buffer times 2049 db 96h
+
+;=============================================================================
+
+Init: ;Initialization Routine
+
+ TRACER 'I'
+ mov ax,cs ;ds=cs
+ mov ds,ax
+
+%ifdef DEBUG
+; print CS value (load segment)
+ call print_hex16
+%endif
+
+ mov si, Greeting ;Display Greeting
+ call print_string
+
+ mov ax,Unsupported ;Init is executed only once
+ mov [Routines],ax
+
+ mov ax, 5400h
+ int 13h ; Get diskemu status
+ jc FindBoot ; If CF=1 no diskemu loaded
+
+ mov [DriveNumber], cl ; Store drive number
+
+ call keyflag
+ and al, 8 ; alt key ?
+ jz extread
+
+ mov si, DrvNumMsg ; Display "drive number="
+ call print_string
+ mov al, [DriveNumber]
+ call print_hex8
+ mov si, LineEnd ; CR/LF
+ call print_string
+ jmp extread
+
+; Diskemu is not loaded
+; so loop to find drive number
+ ; *** start of 1.4 changes ***
+ ; ??? mov dl, 0ffh ;Start at Drive 0xff
+ ; *** FindBoot at c47 in 1.4, at c0c in 1.3 ***
+FindBoot: call ScanDrives ; call new helper in 1.4
+ jnc FoundBoot ; ded*df3
+; mov si,offset SpecPkt ;Locate booted CD-ROM drive
+; mov [SpecPkt],0 ;Clear 1st byte of SpecPkt
+; mov ax,4B01h ;Get Bootable CD-ROM Status
+; int 13h
+; jnc FindPass ;If booted CD found
+;
+; Carry is not cleared in buggy Dell BIOSes,
+; so I'm checking packet size byte
+; some bogus bioses (Dell Inspiron 2500) returns packet size 0xff when failed
+; Dell Dimension XPsT returns packet size 0x14 when OK
+
+; cmp [SpecPkt], 0
+; jne FoundBoot
+
+; cmp [SpecPkt], 13h ; anything between 13h and 20h should be OK
+; jb FindFail
+; cmp [SpecPkt], 20h
+; ja FindFail
+; jmp short FoundBoot
+;
+; FindFail:
+; dec dl ;Next drive
+; cmp dl, 80h
+; jae FindBoot ;Check from ffh..80h
+ ; *** end of 1.4 changes ***
+
+ mov si,NoBootCD ;No booted CD found,
+ call print_string
+ jmp NoEndAddr ;Do not install driver
+
+FoundBoot:
+; mov dl, [SpecPkt+2] ; 1.4 change
+ ; *** next line at c57 in 1.4, at c3d in 1.3 ***
+ mov [DriveNumber],dl ;Booted CD-ROM found,
+ ; so save Drive #
+
+ call keyflag
+ and al, 8 ; alt key ?
+ jz extread
+
+ mov si, CDStat
+ call print_string
+ mov si, SpecPkt ;Point to returned CD SpecPkt
+ mov cx, 19 ; containing 19 bytes
+StatDump: mov al, ' ' ;Print a space
+ call print_char
+ mov al, byte [si] ;Hexdump a SpecPkt byte
+ call print_hex8
+ inc si ;Point to next byte
+ loop StatDump
+
+ mov si, LineEnd ;Print a CR/LF
+ call print_string
+
+extread:
+;See how many CD Sector bytes are returned by an Extended Read
+ mov byte [SpecPkt],16 ;SpecPkt Size
+ mov byte [SpecPkt+1],0 ;Reserved
+ mov word [SpecPkt+2],1 ;Transfer one sector
+ mov word [SpecPkt+6],cs ;Into our Buffer
+ mov word [SpecPkt+4],Buffer
+ mov word [SpecPkt+8],16 ;From CD Sector 16
+ mov word [SpecPkt+10],0
+ mov word [SpecPkt+12],0
+ mov word [SpecPkt+14],0
+
+ mov si, SpecPkt ;Set ds:si --> SpecPkt
+ mov dl, [DriveNumber]
+ mov ah, 42h ;Extended Read
+ int 13h
+ jnc SecSize ;If success
+
+ mov ah, 42h ;Always make 2 read attempts
+ int 13h
+ ;How many bytes did we get?
+SecSize: std ;Count down
+ mov ax,cs ;Point to end of Buffer
+ mov es,ax
+ mov di,Buffer+2047 ;Find end of read data
+ mov si,Buffer+2048
+ mov cx,2049
+ repe cmpsb ;cx = number of bytes read
+
+ cld ;Restore count direction to up
+ mov si,CDBytes ;Display number of bytes read
+ call print_string
+
+ mov al, [DriveNumber]
+ call print_hex8
+
+ mov si,CDBytesA ;Remainder A of message
+ call print_string
+
+ mov al,ch ;Hex-dump cx
+ and al,0Fh ;Second nibble
+ call print_hex8 ; (don't need the First)
+ mov al,cl
+ call print_hex8 ; (don't need the First)
+
+ mov si,CDBytesB ;Remainder B of message
+ call print_string
+
+ cmp cx,2048 ;Did we read 2048 bytes?
+ je ParseParm ;If yes <-- O.K.
+
+ mov byte [ReadBytes],1
+ cmp cx,1024 ;Did we read 1024 bytes?
+ je ParseParm ;If yes <-- O.K.
+
+ mov byte [ReadBytes],2
+ cmp cx,512 ;Did we read 512 bytes?
+ jne NoEndAddr ;If not, do not load driver
+
+ParseParm: mov bx,word [cs:ReqHdrLoc] ;Parse command line
+ mov es,word [cs:ReqHdrLoc+2] ; parameters
+ mov si,[es:bx+18] ;Get BPB array ptr into DS:SI
+ mov ds,[es:bx+20]
+FindParm: inc si
+FindParm1: cmp byte [si],0Dh ;CR? (End of parameters)
+ je EndOfParms
+
+ cmp byte [si],0Ah ;LF?
+ je EndOfParms
+
+ cmp byte [si],'/' ;A parameter?
+ jne FindParm
+
+ inc si
+ cmp byte [si],'D' ;Device Name parameter?
+ jne FindParm1
+
+ inc si
+ cmp byte [si],':'
+ jne FindParm1
+
+;bbb
+ push si
+ mov si, DevName ;Device Name is at ds:si
+ push ds ;Keep ptr to Device Name
+ mov ax, cs
+ mov ds, ax
+ call print_string
+ pop ds ;Retrieve Device Name ptr
+ pop si
+ mov cx, 8 ;Get next 8 chars
+ inc si ; = Device Name
+ mov ax, cs
+ mov es, ax
+ mov di, DeviceName
+NextChar: cmp byte [si],' '
+ ja AboveSpace
+
+ mov ax,cs ;Pad end of Device Name with
+ mov ds,ax ; spaces if necessary
+ mov si,DblSpace ;A space
+AboveSpace: mov al, [si]
+ call print_char
+ movsb ;ds:[si] --> es:[di]
+ loop NextChar
+
+ mov si,LineEnd
+ mov ax,cs
+ mov ds,ax
+ call print_string
+
+ mov ax,Init-2 ;Last byte of driver to keep
+ jmp EndAddr ;Install driver
+
+EndOfParms:
+ mov ax, cs ; Restore segment registers (fix)
+ mov ds, ax
+ mov es, ax
+
+ mov si,NoDevName ;No Device Name Found
+ call print_string
+
+NoEndAddr: mov ax,0 ;Do not install driver
+
+EndAddr: mov es,[ReqHdrLoc+2] ;Write End Address
+ mov bx,[ReqHdrLoc]
+ mov [es:bx+14],ax
+ mov [es:bx+16],cs
+ mov bx,ax ;Hold onto install status
+
+ mov si, DrvInst ;Display driver install status
+ call print_string
+ mov si, DrvInst1 ;Assume driver installed
+ cmp bx,0 ;Was driver installed?
+ jne DrvStatus ;If yes
+ mov si, NoDrvInst ;Driver not installed
+DrvStatus: call print_string
+
+ mov ax,0 ;Set Return Status = success
+ cmp bx,0 ;Was INIT successful?
+ jne InitStat ;If yes
+ mov ax,800Ch ;Status = General Failure
+InitStat:
+ push ax ;Save Return Status
+
+ call keyflag
+ and al, 8 ; alt key ?
+ jz InitExit
+
+WaitHere:
+ mov si, WaitMsg ;Display Halted message
+ call print_string
+
+AltWait:
+ call keyflag
+ and al, 8 ; Alt key?
+ jnz AltWait ; Pressed? yes -> wait
+
+InitExit:
+ pop ax ;Retrieve Return Status
+ TRACER 'i'
+ retn ;That's it for Init!
+
+ ; *** start 1.4 changes at ded ***
+SpecGo: mov si,SpecPkt
+ int 13h
+ retn
+
+ScanDrives: push ax ; at df3 in 1.4
+ push si
+ mov dl, 7fh ;Start at Drive 0x80
+NextDrv: inc dl
+ clc
+ mov ax,4B01h ;Get Bootable CD-ROM Status
+ mov BYTE [SpecPkt],0 ;Clear 1st byte of SpecPkt
+ call SpecGo
+; Carry is not cleared in buggy Dell BIOSes,
+; so I'm checking packet size byte
+; some bogus bioses (Dell Inspiron 2500) returns packet size 0xff when failed
+; Dell Dimension XPsT returns packet size 0x14 when OK
+
+ cmp BYTE [SpecPkt], 13h ; anything between 13h and 20h should be OK
+ jb FindFail
+ cmp BYTE [SpecPkt], 20h
+ ja FindFail ; in 1.4 at e16
+ jmp short SendFound ; in 1.4 at e26
+
+FindFail: cmp dl, 0ffh
+ je SendFail ; Check from 80h..ffh
+ jmp short NextDrv ;Next drive
+SendFail: xor dl,dl
+ stc
+ jmp short ThingDone
+SendFound: mov dl, [SpecPkt+2]
+ clc
+ThingDone: pop si
+ pop ax
+ retn
+ ; *** end 1.4 changes ***
+
+;=============================================================================
+
+;------------------------------------------------------------
+; keyboard flags - return keyboard flags in AL
+; bit 3 = ALT key
+keyflag: ; at dbc in 1.3, at e2e in 1.4
+ push bx
+ mov ah, 2
+ int 16h
+ pop bx
+ retn
+
+;=============================================================================
+
+DrvNumMsg db ' Diskemxx.bin returned drive number=', 0
+NoBootCD db ' No booted CD-ROM found.',CR,0
+
+CDStat db ' INT 13h / AX=4B01h Specification Packet for '
+ db 'Booted CD-ROM:',CR,' ', 0
+
+CDBytes db ' Drive ', 0
+CDBytesA db ' returns ', 0
+CDBytesB db 'h bytes per Sector.',CR,0
+
+DevName db ' Device Name: ', 0
+NoDevName db ' No Device Name found. '
+ db 'Usage: device=eltorito.sys /D:<DevName>',CR,0
+
+DrvInst db ' Driver ', 0
+NoDrvInst db 7,'not ' ;7 = Ctrl-G = Beep
+DrvInst1 db 'installed',CR,0
+
+WaitMsg db ' Alt pressed, waiting...', CR, 0
+;ContMsg db ' Continuing...'
+LineEnd db CR,0
+
+
+;=============================================================================
diff --git a/contrib/syslinux-4.02/dosutil/eltorito.txt b/contrib/syslinux-4.02/dosutil/eltorito.txt
new file mode 100644
index 0000000..956e54f
--- /dev/null
+++ b/contrib/syslinux-4.02/dosutil/eltorito.txt
@@ -0,0 +1,50 @@
+
+Change log for eltorito.asm, by Bart Lagerweij
+
+Jun 25, 2009 - License source code under the MIT license
+
+Jun 6, 2002 - v1.2
+Eltorito.sys does now also finds the correct driver number for the booted CD-Rom
+on a Dell PC with very buggy BIOS. It does not clear the carry flag after a
+succesfull call to int13/ax=4b01h call. Other PC's also using Phoenix BIOS
+version 1.10 A14, or alike maybe also benefit from this "workaround".
+
+Mar 9, 2002
+- All read requests are now retried 5 times.
+- Bug fix, had...
+ cmp ax, 3FFFh ;Too large?
+ ja ReadLBad ;If yes
+ seperated from...
+ mov ax,es:[bx+18] ;Get number of sectors to read
+ mov word ptr [SpecPkt+2],ax
+ so, it was checking "wild" ax values...
+- Some cleanup and small changes
+- The tracers give trouble when using SHCD..
+- Reverted proc ReadL back to Rev. 0.15BETA
+
+Mar 5, 2002
+- Bug fix, when changing CD media some machines would "hang" in the PriVolDesc
+ routine.
+- Added printing of TRACER characters to trace the bug above
+- Major cleanup and now using ASCIIZ strings
+
+May 9, 2001
+- Fixed a "pad devicename with spaces" bug, this only happened when a device
+ name was used with less than 8 characters, for example, "MSCD000" became
+ "MSCD000("
+- Bug fix, when eltorito.sys was called with invalid command line parameters,
+ garbage was printed and sometimes followed by "system halted" that has been
+ there since the very first version of eltorito.sys. I know that because I
+ had the bug back then. When loading eltorito.sys using a device loader,
+ for example "device.com eltorito.sys /test:123" garbage was printed instead
+ of "No device name found." "driver not installed".
+ Changed the error message to include a "usage" string.
+
+May 8, 2001
+- If diskemu.bin is loaded eltorito.sys uses the drivenumber from diskemu
+ A call is made to "diskemu/Get status" (INT13/AX=5400) and the drivenumber is returned in CL
+ This should fix boot problems on Dell PCs (YES!)
+ When diskemu.bin is not loaded, eltorito still loops all drive numbers using eltorito calls.
+- Removed "press Escape..."
+- When the Alt-key is pressed (and holded) more info is printed and eltorito.sys halts
+
diff --git a/contrib/syslinux-4.02/dosutil/mdiskchk.c b/contrib/syslinux-4.02/dosutil/mdiskchk.c
new file mode 100644
index 0000000..47bb08e
--- /dev/null
+++ b/contrib/syslinux-4.02/dosutil/mdiskchk.c
@@ -0,0 +1,357 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved
+ * Portions copyright 2010 Shao Miller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * mdiskchk.c
+ *
+ * DOS program to check for the existence of a memdisk.
+ *
+ * This program can be compiled for DOS with the OpenWatcom compiler
+ * (http://www.openwatcom.org/):
+ *
+ * wcl -3 -osx -mt mdiskchk.c
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <i86.h> /* For MK_FP() */
+
+typedef unsigned long uint32_t;
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+
+/* Pull in MEMDISK common structures */
+#include "../memdisk/mstructs.h"
+
+struct memdiskinfo {
+ struct mdi mdi;
+
+ /* We add our own fields at the end */
+ int cylinders;
+ int heads;
+ int sectors;
+};
+
+struct memdiskinfo *query_memdisk(int drive)
+{
+ static struct memdiskinfo mm;
+ uint32_t _eax, _ebx, _ecx, _edx;
+ uint16_t _es, _di;
+ unsigned char _dl = drive;
+ uint16_t bytes;
+
+ __asm {
+ .386;
+ mov eax, 454d0800h;
+ mov ecx, 444d0000h;
+ mov edx, 53490000h;
+ mov dl, _dl;
+ mov ebx, 3f4b0000h;
+ int 13h;
+ mov _eax, eax;
+ mov _ecx, ecx;
+ mov _edx, edx;
+ mov _ebx, ebx;
+ mov _es, es;
+ mov _di, di;
+ }
+
+ if (_eax >> 16 != 0x4d21 ||
+ _ecx >> 16 != 0x4d45 || _edx >> 16 != 0x4944 || _ebx >> 16 != 0x4b53)
+ return NULL;
+
+ memset(&mm, 0, sizeof mm);
+
+ bytes = *(uint16_t far *) MK_FP(_es, _di);
+
+ /* 27 is the most we know how to handle */
+ if (bytes > 27)
+ bytes = 27;
+
+ _fmemcpy((void far *)&mm, (void far *)MK_FP(_es, _di), bytes);
+
+ mm.cylinders = ((_ecx >> 8) & 0xff) + ((_ecx & 0xc0) << 2) + 1;
+ mm.heads = ((_edx >> 8) & 0xff) + 1;
+ mm.sectors = (_ecx & 0x3f);
+
+ return &mm;
+}
+
+const char *bootloadername(uint8_t id)
+{
+ static const struct {
+ uint8_t id, mask;
+ const char *name;
+ } *lp, list[] = {
+ {0x00, 0xf0, "LILO"},
+ {0x10, 0xf0, "LOADLIN"},
+ {0x31, 0xff, "SYSLINUX"},
+ {0x32, 0xff, "PXELINUX"},
+ {0x33, 0xff, "ISOLINUX"},
+ {0x34, 0xff, "EXTLINUX"},
+ {0x30, 0xf0, "SYSLINUX family"},
+ {0x40, 0xf0, "Etherboot"},
+ {0x50, 0xf0, "ELILO"},
+ {0x70, 0xf0, "GrUB"},
+ {0x80, 0xf0, "U-Boot"},
+ {0xA0, 0xf0, "Gujin"},
+ {0xB0, 0xf0, "Qemu"},
+ {0x00, 0x00, "unknown"}
+ };
+
+ for (lp = list;; lp++) {
+ if (((id ^ lp->id) & lp->mask) == 0)
+ return lp->name;
+ }
+}
+
+/* The function type for an output function */
+#define OUTPUT_FUNC_DECL(x) \
+void x(const int d, const struct memdiskinfo * const m)
+typedef OUTPUT_FUNC_DECL((*output_func));
+
+/* Show MEMDISK information for the passed structure */
+static OUTPUT_FUNC_DECL(normal_output)
+{
+ if (m == NULL)
+ return;
+ printf("Drive %02X is MEMDISK %u.%02u:\n"
+ "\tAddress = 0x%08lx, len = %lu sectors, chs = %u/%u/%u,\n"
+ "\tloader = 0x%02x (%s),\n"
+ "\tcmdline = %Fs\n",
+ d, m->mdi.version_major, m->mdi.version_minor,
+ m->mdi.diskbuf, m->mdi.disksize, m->cylinders, m->heads, m->sectors,
+ m->mdi.bootloaderid, bootloadername(m->mdi.bootloaderid),
+ MK_FP(m->mdi.cmdline.seg_off.segment,
+ m->mdi.cmdline.seg_off.offset));
+}
+
+/* Yield DOS SET command(s) as output for each MEMDISK kernel argument */
+static OUTPUT_FUNC_DECL(batch_output)
+{
+ if (m != NULL) {
+ char buf[256], *bc;
+ const char far *c =
+ MK_FP(m->mdi.cmdline.seg_off.segment,
+ m->mdi.cmdline.seg_off.offset);
+ const char *have_equals, is_set[] = "=1";
+
+ while (*c != '\0') {
+ /* Skip whitespace */
+ while (isspace(*c))
+ c++;
+ if (*c == '\0')
+ /* Trailing whitespace. That's enough processing */
+ break;
+ /* Walk the kernel arguments while filling the buffer,
+ * looking for space or NUL or checking for a full buffer
+ */
+ bc = buf;
+ have_equals = is_set;
+ while ((*c != '\0') && !isspace(*c) &&
+ (bc < &buf[sizeof(buf) - 1])) {
+ /* Check if the param is "x=y" */
+ if (*c == '=')
+ /* "=1" not needed */
+ have_equals = &is_set[sizeof(is_set) - 1];
+ *bc = *c;
+ c++;
+ bc++;
+ }
+ /* Found the end of the parameter and optional value sequence */
+ *bc = '\0';
+ printf("set %s%s\n", buf, have_equals);
+ }
+ }
+}
+
+/* We do not output batch file output by default. We show MEMDISK info */
+static output_func show_memdisk = normal_output;
+
+/* A generic function type */
+#define MDISKCHK_FUNC_DECL(x) \
+void x(void)
+typedef MDISKCHK_FUNC_DECL((*mdiskchk_func));
+
+static MDISKCHK_FUNC_DECL(do_nothing)
+{
+ return;
+}
+
+static MDISKCHK_FUNC_DECL(show_usage)
+{
+ printf("\nUsage: mdiskchk [--safe-hooks] [--mbfts] [--batch-output]\n"
+ "\n"
+ "Action: --safe-hooks . . Will scan INT 13h \"safe hook\" chain\n"
+ " --mbfts . . . . Will scan memory for MEMDISK mBFTs\n"
+ " --batch-output . Will output SET command output based\n"
+ " on MEMDISK kernel arguments\n"
+ " --no-sequential Suppresses probing all drive numbers\n");
+}
+
+/* Search memory for mBFTs and report them via the output method */
+static MDISKCHK_FUNC_DECL(show_mbfts)
+{
+ const uint16_t far * const free_base_mem =
+ MK_FP(0x0040, 0x0013);
+ int seg;
+ uint8_t chksum;
+ uint32_t i;
+ const struct mBFT far *mbft;
+ struct memdiskinfo m;
+ struct patch_area far *patch_area;
+
+ for (seg = *free_base_mem / 16; seg < 0x9FFF; seg++) {
+ mbft = MK_FP(seg, 0);
+ /* Check for signature */
+ if (mbft->acpi.signature[0] != 'm' ||
+ mbft->acpi.signature[1] != 'B' ||
+ mbft->acpi.signature[2] != 'F' ||
+ mbft->acpi.signature[3] != 'T')
+ continue;
+ if (mbft->acpi.length != sizeof(struct mBFT))
+ continue;
+ /* Check sum */
+ chksum = 0;
+ for (i = 0; i < sizeof(struct mBFT); i++)
+ chksum += ((const uint8_t far *)mbft)[i];
+ if (chksum)
+ continue;
+ /* Copy the MDI from the mBFT */
+ _fmemcpy((void far *)&m, &mbft->mdi, sizeof(struct mdi));
+ /* Adjust C/H/S since we actually know
+ * it directly for any MEMDISK with an mBFT
+ */
+ patch_area = (struct patch_area far *)&mbft->mdi;
+ m.cylinders = patch_area->cylinders;
+ m.heads = patch_area->heads;
+ m.sectors = patch_area->sectors;
+ show_memdisk(patch_area->driveno, &m);
+ }
+}
+
+/* Walk the "safe hook" chain as far as possible
+ * and report MEMDISKs that we find via the output method
+ */
+static MDISKCHK_FUNC_DECL(show_safe_hooks)
+{
+ const real_addr_t far * const int13 =
+ MK_FP(0x0000, 0x0013 * sizeof(real_addr_t));
+ const struct safe_hook far *hook =
+ MK_FP(int13->seg_off.segment, int13->seg_off.offset);
+
+ while ((hook->signature[0] == '$') &&
+ (hook->signature[1] == 'I') &&
+ (hook->signature[2] == 'N') &&
+ (hook->signature[3] == 'T') &&
+ (hook->signature[4] == '1') &&
+ (hook->signature[5] == '3') &&
+ (hook->signature[6] == 'S') &&
+ (hook->signature[7] == 'F')) {
+ /* Found a valid "safe hook" */
+ if ((hook->vendor[0] == 'M') &&
+ (hook->vendor[1] == 'E') &&
+ (hook->vendor[2] == 'M') &&
+ (hook->vendor[3] == 'D') &&
+ (hook->vendor[4] == 'I') &&
+ (hook->vendor[5] == 'S') &&
+ (hook->vendor[6] == 'K')) {
+ /* Found a valid MEMDISK "safe hook". It will have an mBFT */
+ const struct mBFT far *mbft;
+ struct memdiskinfo m;
+ struct patch_area far *patch_area;
+
+ /* Copy the MDI from the mBFT. Offset is a misnomer here */
+ mbft = MK_FP(hook->mbft >> 4, 0); /* Always aligned */
+ _fmemcpy((void far *)&m, &mbft->mdi, sizeof(struct mdi));
+ /* Adjust C/H/S since we actually know
+ * it directly for any MEMDISK with an mBFT
+ */
+ patch_area = (struct patch_area far *)&mbft->mdi;
+ m.cylinders = patch_area->cylinders;
+ m.heads = patch_area->heads;
+ m.sectors = patch_area->sectors;
+ show_memdisk(patch_area->driveno, &m);
+ } /* if */
+ /* Step to the next hook in the "safe hook" chain */
+ hook = MK_FP(hook->old_hook.seg_off.segment,
+ hook->old_hook.seg_off.offset);
+ } /* while */
+}
+
+int main(int argc, char *argv[])
+{
+ int d;
+ int found = 0;
+ int sequential_scan = 1; /* Classic behaviour */
+ const struct memdiskinfo *m;
+
+ /* Default behaviour */
+ mdiskchk_func usage = do_nothing,
+ safe_hooks = do_nothing,
+ mbfts = do_nothing;
+
+ /* For each argument */
+ while (--argc) {
+ /* Argument should begin with one of these chars */
+ if ((*argv[argc] != '/') && (*argv[argc] != '-')) {
+ /* It doesn't. Print usage soon */
+ usage = show_usage;
+ break;
+ }
+ argv[argc]++;
+
+ /* Next char might be '-' as in "--safe-hooks" */
+ if (*argv[argc] == '-')
+ argv[argc]++;
+
+ switch (*argv[argc]) {
+ case 'S':
+ case 's':
+ safe_hooks = show_safe_hooks;
+ break;
+ case 'M':
+ case 'm':
+ mbfts = show_mbfts;
+ break;
+ case 'B':
+ case 'b':
+ show_memdisk = batch_output;
+ break;
+ case 'N':
+ case 'n':
+ sequential_scan = 0;
+ break;
+ default:
+ usage = show_usage;
+ } /* switch */
+ } /* while */
+
+ safe_hooks();
+ mbfts();
+ if (!sequential_scan)
+ goto skip_sequential;
+ for (d = 0; d <= 0xff; d++) {
+ m = query_memdisk(d);
+ if (m != NULL) {
+ found++;
+ show_memdisk(d, m);
+ }
+ }
+skip_sequential:
+ usage();
+
+ return found;
+}
+
diff --git a/contrib/syslinux-4.02/dosutil/mdiskchk.com b/contrib/syslinux-4.02/dosutil/mdiskchk.com
new file mode 100644
index 0000000..22ccfe5
--- /dev/null
+++ b/contrib/syslinux-4.02/dosutil/mdiskchk.com
Binary files differ