贡献个垃圾的光盘引导代码吧.....准备换FAT32的U盘启动了.渣虚拟机伤不起啊..
(包含文件可以忽略....)
;[DEFINITIONS]
%define_REAL_MODE_
%include"./include/GlobalData.inc"
%include"./include/Graphics.inc"
BUFFEREQU0x200
PRIM_DESC_LBAEQU16
DESC_ROOT_DIREQUBUFFER + 156
MODULE_SETUP_SEGEQU0x0800
;[END DEFINITIONS]
[BITS16]
;[SECTION CODE]
;[START BOOT AT 0x7C00]
;Initialize registers
movax, 0x07C0; `
movds,ax; | Set ES = DS = 0x7C0
moves, ax; /
shlax, 4
cli
movsp, ax; `
xorax, ax; | Set SS:SP = 0x7C00
movss, ax; /
sti
movgs, ax;GS = 0,Now for access global data
movax, 0xB800;
movfs, ax;FS = Text Mode VRAM(0xB800)
;Screen settings
movax, TELETYPE_80X25
int0x10;Clear screen & set video mode
mov ah, 0x01
movcx, 0x2000
int0x10;Get off the cursor......
;Store global data
callStoreGlobalData
;Print a string
movsi, msg1; DS:SI = string address
movah, COLOR_BKG_BLACK | COLOR_WHITE
cld;See function @prints
callprints
mov ax, PRIM_DESC_LBA
mov cx, 1
mov di, BUFFER
call ReadSector
movdi, DESC_ROOT_DIR
callLoadDirTable
movsi, filename
callSearchForFile
mov ax, [di + 2] ; LBA Address
mov cx, [di + 10] ; Size of file
add cx, 2048
shr cx, 11 ; Change unit from byte to sector
mov di, 0x400
movdl, [bDriveNum]
call ReadSector
jmpMODULE_SETUP_SEG : 0
;[END CODE]
;[SUBROUTINES]
;function @prints : Print a string with attribute should manually set
;writing VRAM
;#param:DS:SI = string address
;AH = attribute(color)
;#change:[wPrintPos],AX,BX,SI,DI
;#assume:FS = 0xB800,DF = 0
prints:
movdi, word [wPrintPos]
.loop:
lodsb
oral, al
jz.end
cmpal,10
je.newline
mov word [fs:di], ax;assume:FS = 0xB800
adddi, 2
jmp.loop
.newline:
pushax
movax, di
movbl, 160
divbl
xorah, ah
incal
movbl, 160
mulbl
movdi, ax
popax
jmp.loop
.end
movword [wPrintPos], di
ret
;function
@strlen : Get length of the string
;#param:ES:SI = target string
;#ret:CX = string length
;#change:AX
strlen:
movdi, si
orcx, 0xFFFF
xoral, al
repnzscasb
notcx
deccx
ret
;function @SearchForFile : Search for file in directory in BUFFER
;#param: SI = file name (string address)
;#change:AX,CX,DX,DI
SearchForFile:
call strlen ; Get length of file name
mov di, BUFFER
.loop:
movzx ax, byte [di] ; Get size of record
or ax, ax ; If zero, no more record is available
jz .error
movzx dx, byte [di + 32] ; Get length of actual filename
cmp cx, dx ; If not equal, next record
jnz .next
push si
push di
add di, 33 ; Set DI to the actual filename
repe cmpsb
pop di
pop si
jz .done
.next:
add di, ax ; Point to the next record
jmp .loop
.done:
ret
.error:
movah, COLOR_BKG_BLACK | COLOR_LIGHTRED
call prints
mov si, errormsg
call prints
cli
hlt
;function @LoadDirTable : Load directory table into memory
;#param: DI = (address of) directory entry
;#change:AX,CX,DI
LoadDirTable:
moveax, dword [di + 2]
movcx, 1
movdi, BUFFER
callReadSector
ret
;function @ReadSector : Read a sector from the boot device
;#param:DL = drive number
;AX = LBA address of the first sector to read
;CX = sectors count
;DS:SI = DAP
;DS:DI = buffer address
;#assume:DAP present & exist
;#change:AX
ReadSector:
movword [DAP.LBA], ax
movword [DAP.sectorCount], cx
movword [DAP.bufferSegment], ds
movword [DAP.bufferOffset], di
movsi, DAP
movah, 0x42
int0x13
ret
;function @StoreGlobalData : As the name
;#param:NULL
;#change:
StoreGlobalData:
movbyte [bDriveNum], dl
movword [wPrintPos], 0
movbyte [bVideoMode], 3
movbyte [bScrnWidth], 80
movbyte [bScrnHeight], 25
movdword [dVideoRAMAddr], 0x000B8000
ret
;[END SUBROUTINES]
;[SECTION DATA]
DAP:;DiskAddressPacket
.packetSizedb16
.reserveddb0
.sectorCountdw0
.bufferOffsetdw0
.bufferSegmentdw0
.LBAdq0
msg1db"Booting from CDROM......",10,0
filenamedb"SETUP.BIN",0
errormsgdb" doesn*t exist in CDROM.Halt.",0
;Fill up the free space
times510-($-$$)db0x90
;Boot Sector Signature
dw0xAA55
;[END DATA]
;[END BOOT]