Index: bootcd/isolinux/syslinux-6.03/dosutil/copybs.asm
===================================================================
--- bootcd/isolinux/syslinux-6.03/dosutil/copybs.asm	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/dosutil/copybs.asm	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -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
