Code: Select all
;************************************************************************
;*
;* Description: This is a BOOT sector source Code, for compiling with NASM
;* How to Compile?: < NASM -f bin BOOT.asm -o BOOT.bin >
;* Comments: This Boot sector is compatible with the FAT file system.
;* How to Get NASM?: Ask Google! (NASM is a free ASM compiler).
;*
;* Enjoy!!!
;************************************************************************
[BITS 16] ;//Use 16 bit assembler.
;************************************************************************
ORG 7C00h ;//Because BIOS loads the OS to
;// address 0:7C00h, so ORG 7C00h
;// makes that the reference to date and code
;// are with the right offset (7c00h).
;************************************************************************
;// CS = 0 / IP = 7C00h // SS = ? / SP = ?
;// You are now at address 7c00.
JMP Start ;//Here we start the, BIOS gave us now the control.
;************************************************************************
;* Here goes all the data of the program.
;************************************************************************
;//BIOS Parameter Block
OSName db 'SZK-OS..';//8 byte.
BytesPerSector_BPB dw 512
SectorsPerCluster db 1
ReservedSectors dw 1
NumberOfFATCopies db 2
NumberOfPossibleRootEntries dw 224
Small_NumberOfSectors dw 2880 ;//18 * 80 * 2
MediaDscriptor db 0F0h ;//Fixed disk 0xF8.
SectorsPerFAT dw 9
SectorsPerTrack_BPB dw 18
NumberOfHeads dw 2
HiddenSectors dd 0
Large_NumberOfSectors dd 0
;//Extended BIOS Parameter Block
DriveNumber db 0 ;//0x80 for hard disks
Reserved db 0
ExtendedBootSignature db 29h ;//Extended boot signature
;//(0x29). This is a signature
;// byte that indicates that the
;// following three fields in the
;// boot sector are present.
VolumeSerialNumber dd 123456h
VolumeLabel db '1234567890_' ;//11 byte.
FileSystemType db 'FAT12 ' ;//8 byte.
;************************************************************************
;//Messages Strings.
szErrorReadingDrive db 'Error Reading Drive, Press any Key to reboot...',0
szHelloWorld db 'Hello World!...',0
;************************************************************************
nTracksToRead db 3 ;//Read 3 Tracks (1 Track = 512*18 = 9,216 bytes)(Modify this value to how much Tracks you want to
read).
;************************************************************************
;//For Screen manipulation.
xCursor db 0
yCursor db 0
;************************************************************************
;//
nSide db 1 ;//Start Reading the other side.
nTrack db 0 ;//Track 0
nSector db 16 ;//33 sectors are reserved (1 Boot sector + 2 FAT's (9*2) + Directory (14)).
;//for Hard disks - nTrack dw 0
;************************************************************************
nTrays db 0
;************************************************************************
;*Pointer to the download area.
pOS dw 0h ;//Points to were to download the Operating System.
;************************************************************************
;*Disk Paremeter Table.
StepRateAndHeadUnloadTime db 0DFh
HeadLoadTimeAndDMAModeFlag db 2h
DelayForMotorTurnOff db 25h
BytesPerSector db 2h ;// (1 = 256) //(2 = 512 bytes)
SectorsPerTrack db 18 ;// 18 sectors in a track.
IntersectorGapLength db 1Bh
DataLength db 0FFh
IntersectorGapLengthDuringFormat db 54h
FormatByteValue db 0F6h
HeadSettlingTime db 0Fh
DelayUntilMotorAtNormalSpeed db 8h
;************************************************************************
;// Here the Boot Sector starts.
;************************************************************************
Start:
DB 0EAh ;//(0EAh = Op code of Far jmp)
;//This is for bugy Bios that loads the OS
DW BootSectorContinue ;// to CS:IP = 7C0h:000 but we want that
DW 0 ;// it would be CS:IP = 0:7C00
;// (This points to the same place in the RAM
;// the only different is that its CS and IP
;// are different).
BootSectorContinue:
CLI ;//Clear Interrupt Flag so while setting up the stack any interrupt would not be fired.
MOV AX,50h ;//lets have the stack start at 500h
MOV SS,AX ;//SS:SP = 50h:1000h
MOV SP,1000h ;//Lets make the stack 4,096 bytes.
MOV AX,CS ;//Set the data segment = CS = 0
MOV DS,AX
MOV AX,7E0h ;//Make ES=7E0h . This points to were we would download
MOV ES,AX ;// the stage 2 of the OS loader.
PUSH DL ;//Save the Boot Drive number, for future use
STI ;//Set Back the Interrupt Flag after we finished setting a stack frame.
CALL ClearScreen
LEA WORD AX,[szHelloWorld] ;//Print Hello World!
CALL PrintMessage
CALL GetKey
CALL SetNewDisketteParameterTable ;//SetNewDisketteParameterTable()
CALL DownloadOS
CALL GetKey ;//Call GetKey()
CALL GiveControlToOS ;//Give Control To OS.
;************************************************************************
;//Prints a message to the screen.
;************************************************************************
PrintMessage:
MOV DI,AX ;//AX holds the address of the string to Display.
MOV BYTE [xCursor],1 ;//Column.
ContinuPrinting:
CMP BYTE [DI],0 ;//Did we get to the End of String.
JE EndPrintingMessage ;//if you gat to the end of the string return.
MOV AH,2 ;//Move Cursor
MOV BYTE DH,[yCursor] ;//row.
MOV BYTE DL,[xCursor] ;//column.
MOV BH,0 ;//page number.
INT 10h
INC BYTE [xCursor]
MOV AH,0Ah ;//Display Character Function.
MOV AL,[DI] ;//character to display.
MOV BH,0 ;//page number.
MOV CX,1 ;//number of times to write character
INT 10h
INC DI ;//Go to next character.
JMP ContinuPrinting ;//go to Print Next Character.
EndPrintingMessage:
INC BYTE [yCursor] ;//So Next time the message would be printed in the second line.
CMP BYTE [yCursor],25
JNE dontMoveCorsurToBegin
MOV BYTE [yCursor],0
dontMoveCorsurToBegin:
RET
;************************************************************************
;//Waits for the user to press a key.
;************************************************************************
GetKey:
MOV AH,0
INT 16h ;//Wait for a key press.
RET
;************************************************************************
;//Gives Control To Second Part Loader.
;************************************************************************
GiveControlToOS:
DB 0EAh ;//FAR JMP op code.
DW 0h ;//
DW 7E0h ;//
;************************************************************************
;//Set New Disk Parameter Table
;************************************************************************
SetNewDisketteParameterTable:
LEA WORD DX,[StepRateAndHeadUnloadTime] ;//Get the address of the Disk Parameters Block.
;//Int 1E (that is in address 0:78h)-(1Eh x 4 = 78h).
;// holds the address of the disk parameters
;// block, so now change it to
;// our parameter black.
MOV WORD [0078h],DX ;//DX holds the address of our Parameters block.
MOV WORD [007Ah],0000 ;//Assuming DS = 0.
MOV AH,0 ;//Reset Drive To Update the DisketteParameterTable.
MOV DL,DriveNumber
INT 13H
ret
;************************************************************************
;//DownloadOS
;************************************************************************
DownloadOS:
ContinueDownload:
CMP BYTE [nSector],19 ;//Did we get to end of track.
JNE ContinueReadingDisk
MOV BYTE [nSector],1 ;//And Read Next Sector(Sectors Start with 1 not 0).
CMP BYTE [nSide],0 ;//Check which side we are reading.
JE ChangeDiskSide ;//If nSide =0 ,Change side.
MOV BYTE [nSide],0 ;//If nSide =1 ,Change back side.
MOV BYTE AL,[nTracksToRead] ;//Get nTracks to read
CMP BYTE [nTrack],AL ;//Did we finish reading???
JE EndDownloadingOS
INC BYTE [nTrack] ;//If we got to end of track, Move to next track.
JMP ContinueReadingDisk
ChangeDiskSide:
INC BYTE [nSide] ;//If nSide =0 ,Change side.
ContinueReadingDisk:
;ReadSector();
CALL ReadSector
INC BYTE [nSector] ;<=== <Read Next Sector>.
JMP ContinueDownload ;//If didn't yet finish Loading OS.
EndDownloadingOS:
RET
;************************************************************************
;//Read Sector.
;************************************************************************
ReadSector:
MOV BYTE [nTrays],0 ;//Set nTrays=0
TryAgain:
MOV AH,2 ;//Read Function.
MOV AL,1 ;//Read 1 Sector.
MOV BYTE CH,[nTrack] ;//Track n (For Hard disk the upper 9-10 bits of Track number are in the upper 2 bits of CL).
MOV BYTE CL,[nSector] ;//Remember: Sectors start with 1, not 0.
MOV BYTE DH,[nSide] ;//Side n
MOV BYTE DL,[DriveNumber] ;//Drive n (floppy's start with 0, Hard disks start with 0x80, and CD-ROM with 0xE0).
MOV WORD BX,[pOS] ;//ES:BX points to the address to were to store the sector.
INT 13h
CMP AH,0 ;//Int 13 return Code is in AH.
JE EndReadSector ;//if 'Success' (AH = 0) End function.
MOV AH,0 ;//Else Reset Drive . And Try Again...
MOV BYTE DL,[DriveNumber]
INT 13h
CMP BYTE [nTrays],3 ;//Check if you tried reading more then 3 times.
JE DisplayError ;// if tried 3 Times Display Error.
INC BYTE [nTrays]
JMP TryAgain ;//Try Reading again.
DisplayError:
LEA WORD AX,[szErrorReadingDrive]
Call PrintMessage
Call GetKey
MOV AH,0 ;//Reboot Computer.
INT 19h
EndReadSector:
ADD WORD [pOS],512 ;//Move the pointer (ES:BX = ES:pOS = 0:pOS) 512 bytes.
;//Here you set the variable pOS (pOS points to were BIOS
;//Would load the Next Sector).
RET
;************************************************************************
;//Clear Screen.
;************************************************************************
ClearScreen
MOV AX,0600h ;//Scroll All Screen UP to Clear Screen.
MOV BH,07
MOV CX,0
MOV DX,184Fh
INT 10h
MOV BYTE [xCursor],0 ;//Set Cursor Position So next write would start in the beginning of screen.
MOV BYTE [yCursor],0
RET
;************************************************************************
;//Put a 55AAh (BOOT sector signature) at the end of the BOOT sector.
;************************************************************************
MakeABOOTSectorSigneture:
TIMES 510-($-$$) DB 0 ;//Fills spare space with zeros.
DW 0xAA55 ;//This is the BOOT Sector Signature.
;************************************************************************
;*