Code: Select all
bits 16 ;16-bit m/c
%macro startprint 0
%%loop1:
lodsb ;it copies the byte pointed by si or esi into al and then increaments to point to next byte
or al,al
jz %%printdone ;if no data then return
mov ah,0eh ;0eh is teletype function used to type letter in al register on screen
int 10h
jmp %%loop1
%%printdone:
%endmacro
org 7c00h ;location of boot
start:
jmp loader
presskey db 10,13,"Press Any Key To Boot",0
amtoflowmem db 10,13,"Amount Of Low Memory Is=",0
displaydot db ".",0
processor db 10,13,"386 Processor M/C",0
otherprocessor db 10,13,"Not A 386 Processor .......",10,13,"Rebooting",0
;keypressed resb 1 ;this is how to declare uninitialized data in NASM but in BSS otherwise warning
keyispressed db 10,13,"Key Is Pressed.......",0
enteredintopm db 10,13,"Entered Into Protected Mode.......:D",0
delay:
mov cx,0fffh ;for delay counter
firstdelay:
mov bx,0ffffh ;delay under delay
seconddelay:
nop
dec bx
jnz seconddelay ;operation of second delay
dec cx
jnz firstdelay ;operation of first delay
ret ;return since it was a call
identifycpu:
pushf ;push initial contents of flag reg on to the stack
xor ah,ah ;make ah=0
push ax ;push ax on stack with ah=0 i.e. bits 12-15=0
popf ;pop contents of ax into flags
pushf ;push flag reg newly modified by cpu on stack
pop ax ;pop them into ax
popf ;pop initial contents of flags
and ah,0f0h ;anding will result for 8088/86,ah=00f0h & 286/386,ah=0000h
cmp ah,0f0h
je negative ;for 8088/86 it is equal
mov si,processor
startprint
ret
negative:
mov si,otherprocessor
startprint
mov cl,05h
printdot1: ;for displaying dots next to rebooting msg
mov si,displaydot
lodsb
mov ah,0eh
int 10h ;prints dot on screen
or cl,cl ;check weather 5 dots are printed
jz done ;if yes come out
pusha ;push all registers on to the stack
call delay
popa ;poping of registers
dec cl ;decreament count of dots
jmp printdot1 ;next dot to print
done:
db 0eah ;used since it is a far jump
dw 0000h ;reboot address ffff:0000
dw 0ffffh
gdtr:
dw gdt_end-gdt-1 ;length of GDT
dd gdt
gdt
nullsel equ $-gdt
gdt0
dd 0
dd 0
codesel equ $-gdt
gdtcode
dw 0x0fff
dw 0x000
db 0x00
db 0x09a
db 0x0cf
db 0x00
datasel equ $-gdt
gdtdata
dw 0x0fff
dw 0x000
db 0x00
db 0x092
db 0x00
gdt_end
loader:
xor ax,ax
mov ds,ax
mov es,ax ;initialisation
call identifycpu
mov si,amtoflowmem
startprint
xor ax,ax
int 12h ;for detecting size of low memory nad returns in kb in ax register
mov ch,04h ;no of digits to be display
mov cl,04h ;count for roll
mov bx,ax ;result in bh so roll
rotleft: ;for displaying size of low memory
rol bx,cl ;roll so msb and lsb get interchange
mov al,bl
and al,0fh ;for only lsb
cmp al,09h ;check if digit or letter
jbe notletter
add al,07h ;if letter add 37h else add only 30h
notletter:
add al,30h
mov ah,0eh
int 10h
dec ch ;dec count
jnz rotleft
mov si,presskey ;loads effective of presskey
startprint
fortimer:
mov cl,05h ;since 5 dots to print
printdot:
mov ah,01h
int 16h ;for taking key hit doesnt freeze,returns zf=0 if key is ready else zf=1
pusha
setnz al ;if zf=0 then keypressed=1
cmp al,01
je readytoload
popa
mov si,displaydot
lodsb
mov ah,0eh
int 10h ;prints dot on screen
or cl,cl ;check weather 5 dots are printed
jz comeout ;if yes come out
pusha ;push all registers on to the stack
call delay
popa ;poping of registers
dec cl ;decreament count of dots
jmp printdot ;next dot to print
comeout:
db 0eah
dw 0000h
dw 0ffffh
readytoload:
popa
mov si,keyispressed
startprint
mov ax,2401h
int 15h
cli
;nmi
lgdt [gdtr]
mov eax,cr0
or al,01h
mov cr0,eax
jmp codesel:intopm
bits 32
intopm:
mov ax,datasel
mov ds,ax
mov es,ax
mov si,enteredintopm
pmloop:
lodsb
or al,al
jz exi
mov ah,0eh
int 10h
jmp pmloop
exi:
times 510 - ($-$$) db 0 ;remaining fill with zero
dw 0xAA55 ;boot drive signature