source: bootcd/isolinux/syslinux-6.03/dosutil/copybs.asm @ dd1be7c

Last change on this file since dd1be7c was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 5.2 KB
Line 
1; -*- fundamental -*- (asm-mode sucks)
2; -----------------------------------------------------------------------
3;
4;   Copyright 1998-2008 H. Peter Anvin - All Rights Reserved
5;
6;   This program is free software; you can redistribute it and/or modify
7;   it under the terms of the GNU General Public License as published by
8;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
9;   Boston MA 02111-1307, USA; either version 2 of the License, or
10;   (at your option) any later version; incorporated herein by reference.
11;
12; -----------------------------------------------------------------------
13
14;
15; copybs.asm
16;
17; Small DOS program to copy the boot sector from a drive
18; to a file
19;
20; Usage: copybs <drive>: <file>
21;
22
23                absolute 0
24pspInt20:               resw 1
25pspNextParagraph:       resw 1
26                        resb 1          ; reserved
27pspDispatcher:          resb 5
28pspTerminateVector:     resd 1
29pspControlCVector:      resd 1
30pspCritErrorVector:     resd 1
31                        resw 11         ; reserved
32pspEnvironment:         resw 1
33                        resw 23         ; reserved
34pspFCB_1:               resb 16
35pspFCB_2:               resb 16
36                        resd 1          ; reserved
37pspCommandLen:          resb 1
38pspCommandArg:          resb 127
39
40                section .text
41                org 100h                        ; .COM format
42_start:
43                mov ax,3000h                    ; Get DOS version
44                int 21h
45                xchg al,ah
46                mov [DOSVersion],ax
47                cmp ax,0200h                    ; DOS 2.00 minimum
48                jae dosver_ok
49                mov dx,msg_ancient_err
50                jmp die
51
52                section .bss
53                alignb 2
54DOSVersion:     resw 1
55
56                section .text
57;
58; Scan command line for a drive letter followed by a colon
59;
60dosver_ok:
61                xor cx,cx
62                mov si,pspCommandArg
63                mov cl,[pspCommandLen]
64
65cmdscan1:       jcxz bad_usage                  ; End of command line?
66                lodsb                           ; Load character
67                dec cx
68                cmp al,' '                      ; White space
69                jbe cmdscan1
70                or al,020h                      ; -> lower case
71                cmp al,'a'                      ; Check for letter
72                jb bad_usage
73                cmp al,'z'
74                ja bad_usage
75                sub al,'a'                      ; Convert to zero-based index
76                mov [DriveNo],al                ; Save away drive index
77
78                section .bss
79DriveNo:        resb 1
80
81                section .text
82;
83; Got the leading letter, now the next character must be a colon
84;
85got_letter:     jcxz bad_usage
86                lodsb
87                dec cx
88                cmp al,':'
89                jne bad_usage
90;
91; Got the colon; now we should have at least one whitespace
92; followed by a filename
93;
94got_colon:      jcxz bad_usage
95                lodsb
96                dec cx
97                cmp al,' '
98                ja bad_usage
99
100skipspace:      jcxz bad_usage
101                lodsb
102                dec cx
103                cmp al,' '
104                jbe skipspace
105
106                mov di,FileName
107copyfile:       stosb
108                jcxz got_cmdline
109                lodsb
110                dec cx
111                cmp al,' '
112                ja copyfile
113                jmp short got_cmdline
114
115;
116; We end up here if the command line doesn't parse
117;
118bad_usage:      mov dx,msg_unfair
119                jmp die
120
121                section .data
122msg_unfair:     db 'Usage: copybs <drive>: <filename>', 0Dh, 0Ah, '$'
123
124                section .bss
125                alignb 4
126FileName        resb 256
127
128;
129; Parsed the command line OK.  Get device parameter block to get the
130; sector size.
131;
132                struc DPB
133dpbDrive:       resb 1
134dpbUnit:        resb 1
135dpbSectorSize:  resw 1
136dpbClusterMask: resb 1
137dpbClusterShift: resb 1
138dpbFirstFAT:    resw 1
139dpbFATCount:    resb 1
140dpbRootEntries: resw 1
141dpbFirstSector: resw 1
142dpbMaxCluster:  resw 1
143dpbFATSize:     resw 1
144dpbDirSector:   resw 1
145dpbDriverAddr:  resd 1
146dpbMedia:       resb 1
147dpbFirstAccess: resb 1
148dpbNextDPB:     resd 1
149dpbNextFree:    resw 1
150dpbFreeCnt:     resw 1
151                endstruc
152
153                section .bss
154                alignb 2
155SectorSize      resw 1
156
157                section .text
158got_cmdline:
159                xor al,al                       ; Zero-terminate filename
160                stosb
161
162                mov dl,[DriveNo]
163                inc dl                          ; 1-based
164                mov ah,32h
165                int 21h                         ; Get Drive Parameter Block
166
167                and al,al
168                jnz filesystem_error
169
170                mov dx,[bx+dpbSectorSize]       ; Save sector size
171;
172; Read the boot sector.
173;
174                section .data
175                align 4, db 0
176DISKIO          equ $
177diStartSector:  dd 0                            ; Absolute sector 0
178diSectors:      dw 1                            ; One sector
179diBuffer:       dw SectorBuffer                 ; Buffer offset
180                dw 0                            ; Buffer segment
181
182                section .text
183read_bootsect:
184                mov ax,cs                       ; Set DS <- CS
185                mov ds,ax
186
187                mov [SectorSize],dx             ; Saved sector size from above
188
189                cmp word [DOSVersion],0400h     ; DOS 4.00 has a new interface
190                jae .new
191.old:
192                mov bx,SectorBuffer
193                mov cx,1                        ; One sector
194                jmp short .common
195.new:
196                mov [diBuffer+2],ax             ; == DS
197                mov bx,DISKIO
198                mov cx,-1
199.common:
200                xor dx,dx                       ; Absolute sector 0
201                mov al,[DriveNo]
202                int 25h                         ; DOS absolute disk read
203                pop ax                          ; Remove flags from stack
204                jc disk_read_error
205
206;
207; Open the file and write the boot sector to the file.
208;
209                mov dx,FileName
210                mov cx,0020h                    ; Attribute = ARCHIVE
211                mov ah,3Ch                      ; Create file
212                int 21h
213                jc file_write_error
214
215                mov bx,ax
216                push ax                         ; Handle
217
218                mov cx,[SectorSize]
219                mov dx,SectorBuffer
220                mov ah,40h                      ; Write file
221                int 21h
222                jc file_write_error
223                cmp ax,[SectorSize]
224                jne file_write_error
225
226                pop bx                          ; Handle
227                mov ah,3Eh                      ; Close file
228                int 21h
229                jc file_write_error
230;
231; We're done!
232;
233                mov ax,4C00h                    ; exit(0)
234                int 21h
235
236;
237; Error routine jump
238;
239filesystem_error:
240                mov dx,msg_filesystem_err
241                jmp short die
242disk_read_error:
243                mov dx,msg_read_err
244                jmp short die
245file_write_error:
246                mov dx,msg_write_err
247die:
248                push cs
249                pop ds
250                push dx
251                mov dx,msg_error
252                mov ah,09h
253                int 21h
254                pop dx
255
256                mov ah,09h                      ; Write string
257                int 21h
258
259                mov ax,4C01h                    ; Exit error status
260                int 21h
261
262                section .data
263msg_error:              db 'ERROR: $'
264msg_ancient_err:        db 'DOS version 2.00 or later required', 0Dh, 0Ah, '$'
265msg_filesystem_err:     db 'Filesystem not found on disk', 0Dh, 0Ah, '$'
266msg_read_err:           db 'Boot sector read failed', 0Dh, 0Ah, '$'
267msg_write_err:          db 'File write failed', 0Dh, 0Ah, '$'
268
269                section .bss
270                alignb 4
271SectorBuffer:   resb 4096
Note: See TracBrowser for help on using the repository browser.