;Author     : Daniel, Master Sourcerer at Kitana's Castle
;Last change: June 5, 1998
;Email      : sourcerer@kitana.org


;Reads the boot sector of the first hard disk partition (drive C:)
;and writes it to the file BOOTSEC.BIN


;Code segment
code SEGMENT
ASSUME CS:code,DS:data

start:
;Init data segment
MOV AX,SEG data
MOV DS,AX

;Read boot sector
LEA BX,sectorbuffer
MOV AL,2  ;drive C:
MOV CX,0  ;read first sector
MOV DX,0
CALL readsector
LEA DX,msg_readerror
JC error

;Write sector to file
LEA DX,filename
CALL createfile
LEA DX,msg_writeerror
JC error
LEA DX,sectorbuffer
MOV CX,512
CALL writefile
CALL closefile

;Print success message
LEA DX,msg_success
CALL textout

;Exit program
MOV AX,4C00h
INT 21h

;Print error message and exit program
error:
CALL textout
MOV AX,4C01h
INT 21h


;Reads a sector from a drive
;Input : AL    = drive number (0=A, 1=B, 2=C, ...)
;        DS:BX = buffer to store sector
;        DX:CX = sector number (DX=highword, CX=lowword)
;Output: CF    = success (0=ok, 1=error)
readsector PROC
;Save registers
PUSH AX
PUSH BX
PUSH CX
PUSH DX

;Read 1 sector
MOV WORD PTR sectornumber,CX
MOV WORD PTR sectornumber[2],DX
MOV WORD PTR transferadr,BX
MOV WORD PTR transferadr[2],DS
LEA BX,parameterblock
MOV CX,-1
INT 25h
POP AX  ;this DOS function does not restore the flags from the stack

;Restore registers
POP DX
POP CX
POP BX
POP AX
RET
readsector ENDP


;Create a new file for output
;Input : DS:DX = filename
;Output: BX = file handle
;        CF = succes (0=ok, 1=error)
createfile PROC
;Save registers
PUSH AX
PUSH CX

;Create file
MOV AH,3Ch
XOR CX,CX
INT 21h
MOV BX,AX

;Restore registers
POP CX
POP AX
RET
createfile ENDP


;Writes data to an opened file
;Input : BX    = file handle
;        CX    = number of bytes to write
;        DS:DX = bytes to write
;Output: nothing
writefile PROC
;Save registers
PUSH AX

;Write data
MOV AH,40h
INT 21h

;Restore registers
POP AX
RET
writefile ENDP


;Closes a file handle
;Input : BX = file handle
;Output: nothing
closefile PROC
;Save registers
PUSH AX

;Close file
MOV AH,3Eh
INT 21h

;Restore registers
POP AX
RET
closefile ENDP


;Prints a text (string) to the screen
;Input : DS:DX = address of text
;Output: nothing
textout PROC
PUSH AX
MOV AH,09h
INT 21h  ;output text by DOS
POP AX
RET
textout ENDP

code ENDS



;Data segment
data SEGMENT
parameterblock LABEL WORD
  sectornumber DD 0
      nsectors DW 1
   transferadr DD 0
msg_readerror DB 'Unable to read boot sector.',13,10,36
msg_writeerror DB 'Unable to create output file.',13,10,36
msg_success DB 'Boot sector written to file '
filename DB 'BOOTSEC.BIN',0,'.',13,10,36
sectorbuffer DB 512 DUP(?)
data ENDS



;Stack segment
stck SEGMENT STACK
DW 200 DUP(?)
stck ENDS

END start
