📄 bootsect.asm
字号:
;Ver 2.2 @2003 5.28;Ver 2.1 By Charles @ 2003.4.13;Ver 2.00 By Toby @ 2003.3.27;Ver 1.1 By Charles;Ver 1.00 Created by Toby ;NASM-IDE ASM Assistant Assembler Project File[BITS 16] ;Set code generation to 16 bit mode[ORG 0x7C00] ;Set code start address to 7C00hMEMSTART EQU 8000h; The Fat&Root Temp Position in Memory[SEGMENT .text] ;Main code segment;Before Our Code BIOS Using Real ModeJMP STARTNOP ;Must Be 3 Bytes Longdb 'PCOS' ;Sign Must Be 8 Bytes LongTIMES 0xB-($-$$) db 0 ;Next Line Start at 0x000Bdw 0x200 ;512 bytes per trackdb 0x1 ;An Alloc Unit Have Only One SectorReservedSectors dw 0x1 ;Only One Sector Reserved (Hiden)NumberOfFat db 0x2 ;The Number Of FATRootEntries dw 0xE0 ;The Number Of Root Entriesdw 0xB40 ;Total Sector ;For 3.5 Floppy 2*18*80db 0xF0 ;F0 3.5, 2S, 18Sec 1.44 MB 2.88 MB ;F9 5.25, 2S, 15Sec 720 KB 1.2 MB ;FC 5.25", 1S, 9Sec 180 KB ;FD 5.25", 2S, 9Sec 360 KB ;FE 5.25", 1S, 8Sec 160 KB ;FF 5.25", 2S, 8Sec 320 KB ;F8 N/A Fixed DiskFatSize dw 0x9 ;2880 units * 12 bits per units ;/ 8 bits per bytes ;/ 512 bytes per sectorSectorsPerTrack dw 0x12 ;18 sector per trackNumberOfHeads dw 0x2 ;The Number Of Headsdw 0,0 ;Hiden Sector ??TIMES 0x3E-($-$$) db 0 ;Must Start at 3E;----------------------Load A Sector From Flopppy-----------------;----Load File predo------ReadDataSector:mov ax,[SaveEs] ;The File should be stored at SaveEs:SavePointmov es,ax ;Limit 1000:0000 -- 9000:9E00 512k+40kmov ax,[SavePoint] ;The Sector will be stored at ES:ReadPointmov [ReadPoint],ax ;So I do saved the Es:Readpointjmp StartReadReadSector:mov ax,MEMSTART ;Put 8000h in AX for init Readpointmov [ReadPoint],ax ;init ReadPoint with 8000hjmp ReadFatReadSecond:mov ax,MEMSTART+200hmov [ReadPoint],axReadFat:xor ax,axmov es,ax ;ES:BX must be 0000:8000 or 0000:8200StartRead:mov ax,[SectorToRead] ;Get the SectorToRead to Judge if we should readcmp ax,[Sector] ;if the Sector is loaded ,don't do againje .Return ;if don't need read ,go back.Reset:xor ah,ah ;clear AH for reset drivexor dl,dlint 13h ;reset drivejc .Reset ;redo if failed.Read:xor dx,dxmov ax,[SectorToRead] ;Get to SectorToRead to calc int 13 parametermov cx,[SectorsPerTrack] ;put sector number of a cluster in CL ;to calc Sector Positiondiv cx ;divide ax to two partsmov cx,dx ;the part AL means sector position ,Put in clinc cl ;sector start at 1 not 0xor dx,dxmov bx,[NumberOfHeads]div bxmov dh,dl ;the part AH means head and clusterxor dl,dlmov ch,al ;the part AH put in CH to calc clustermov ax,0201h ;AH is 2 mean read,AL is 1 mean read only one sectormov bx,[ReadPoint] ;the sector will be stored in ReadPointint 13h ;read a data sectorjc .Read ;if failed ,redo.Return:ret ;read successful ,go backSTART:xor ax,axcli ;Stop Interupt for init Stackmov ss,axmov sp,7c00h ;reset Stacksti ;Recover Interruptmov ds,ax ;Set DS=0;----------------------Read Root & Find File---------------;---Calc Root Position---mov ax,[FatSize]mov bl,[NumberOfFat]mul bladd ax,[ReservedSectors];AX=FatSize*NumberOfFat+ReservedSectors ;1.44M AX=9*2+1=13mov [SectorToRead],ax ;AX mean where RootSector is;---Calc Data Position--mov ax,[RootEntries]shr ax,4 ;AX=RootEntries/10,AX is RootSize 1.44M AX=Eadd ax,[SectorToRead] ;Data is saved after Root 1.44M 21dec axdec ax ;I don't why there is two,but there ismov [DataSector],ax ;Saved DataSector 1.44M 1F;---End Calc------ReadRoot:call ReadSector ;Read One RootSectormov di,[ReadPoint] ;Put Sector Begin in DI for search filemov dx,10h ;A Sector can save 10h fileitems ;so we have to compare 10h timesFindFile:mov si,FileName ;Put target filename Begin in SI for compare ;the name is OS.PCSmov cx,0bh ;FileName is 0bh bytes longrepz cmpsb ;compare FileName if it is OS.PCSjz .YetFindadd di,cx ;Mov DI to End of the FileNameadd di,15h ;Mov DI to First of Next FileItemmov cx,[RootEntries]inc word [RootPoint]cmp [RootPoint],cx.Hang:jae .Hangdec dx ;If not Find,Dec DX to Continue Findcmp dx,0 ;compare DX with 0 to Judge If the Sector is endjne FindFile ;If Not End Continue Compinc word [SectorToRead] ;Move Point to Next Sectorjmp ReadRoot ;If End Read Next Sector And Compare.YetFind:mov cx,[es:di+0fh] ;Get File Positionjcxz .YetFind ;If the file is blank,stop;----------------End of FindFile----------------;-----------------Read File---------------------;----Read A Sector------ReadASector:add cx,[DataSector] ;Calc the Absolute Position ;CX=DataSector+FileSectormov [SectorToRead],cx ;Put the FilePosition in SectorToReadcall ReadDataSector ;Read One Sector of File Content;----Find Next Sector---mov bx,[SectorToRead] ;Put SectorToRead in BX for calc Fat Positionsub bx,[DataSector] ;Calc the Position in Data Table ;BX=SectorToRead-DataSectormov cx,bxpush bx ;Save Data Position to Judge First 12 or Last 12shr bx,1 ;Div BX,2add bx,cx ;BX=(SectorToRead-DataSector)*1.5push bx ;Save Floppy Position to Read Fat Itemshr bx,9 ;Calc Position in Fat Sectorsadd bx,[ReservedSectors];Calc Position in Floppymov [SectorToRead],bx ;Put BX in SectorToReadcall ReadSectormov bx,word [SectorToRead]mov [Sector],bxinc word [SectorToRead]call ReadSecondmov ax,[SavePoint] ;Begin Calc Next Data sector position in memoryadd ax,200h ;Add sector size to get new memory positionmov [SavePoint],ax ;Put New Memory Position to SavePoint;######JMP INSIDEjnc .NOADDESmov bx,[SaveEs] ;Get Now Section Positionadd bx,1000h ;Add Section Size to get new section positionmov [SaveEs],bx ;End Calc.NOADDES:;######pop bx ;Load Floppy Position to Read Fat Item;---------OK POP SECOND BX------------------------/and bx,01ffh ;Mod BX,200h to Calc Fat Item Position in Fat Memoryadd bx,MEMSTART ;Calc Fat Item Position in Memorymov cx,[es:bx] ;Load Next Data Sector Positionpop bx ;Load Data Position to Judge First 12 or Last 12;---------OK POP FIRST BX-------------------------------/test bx,1 ;test BX odd or evenje .NOMOVE ;if even,mean Last 12,if odd mean First 12shr cx,4 ;Div cx,16 to move the First 12 to the Last 12.NOMOVE:and cx,0fffh ;Mod cx,1000h to get the Last 12cmp cx,0ff8h ;compare CX with ff8 to test if the file is endjb ReadASector ;if above the file is end otheswise not end;-------------Reset Floppy For Our Driverxor ah,ah ;clear AH for reset drivexor dl,dlint 13h ;reset drive;-----------Ready To Boot -------mov ah,0 ;Set Videomov al,3h ;To 640*480int 10h ;Call BIOScli ; Clear or disable interruptslgdt [gdtr] ; Load GDTmov eax,cr0 ; The lsb of cr0 is the protected mode bitor al,0x01 ; Set protected mode bitmov cr0,eax ; Mov modified word to the control registerjmp codesel:go_pm ; Protected Mode Jump[BITS 32]go_pm : ; Now Protected Modemov ax,dataselmov ds,ax ; Initialise ds & es to data segmentmov es,axmov fs,axmov gs,axmov ss,axmov eax,0x7c00mov esp,eaxjmp dword 0x10000;----------------------------------------------------------FileName db 'OS PCS' ; file to loadSaveEs dw 1000h ; Section for Read FileSavePoint dw 0 ; Position for Read Filegdtr :dw gdt_end-gdt-1 ; Length of the gdtdd gdt ; Physical address of gdtgdt:nullsel equ $-gdt ; $->current location,so nullsel = 0hgdt0: ; Null descriptor,as per convention gdt0 is 0dd 0 ; Each gdt entry is 8 bytes, so at 08h it is CSdd 0 ; In all the segment descriptor is 64 bitscodesel equ $-gdt ; This is 8h,ie 2nd descriptor in gdtcode_gdt: ; Code descriptor 4Gb flat segment at 0000:0000hdw 0x0ffff ; Limit 4Gb bits 0-15 of segment descriptordw 0x0000 ; Base 0h bits 16-31 of segment descriptor (sd)db 0x00 ; Base addr of seg 16-23 of 32bit addr,32-39 of sddb 0x09a ; P,DPL(2),S,TYPE(3),A->Present bit 1,Descriptor ; privilege level 0-3,Segment descriptor 1 ie code ; or data seg descriptor,Type of seg,Accessed bitdb 0x0cf ; Upper 4 bits G,D,0,AVL ->1 segment len is page ; granula, 1 default operation size is 32bit seg ; AVL : Available field for user or OS ; Lower nibble bits 16-19 of segment limitdb 0x00 ; Base addr of seg 24-31 of 32bit addr,56-63 of sddatasel equ $-gdt ; ie 10h, beginning of next 8 bytes or data sddata_gdt: ; Data descriptor 4Gb flat seg at 0000:0000hdw 0x0ffff ; Limit 4Gbdw 0x0000 ; Base 0000:0000hdb 0x00 ; Descriptor format same as abovedb 0x092db 0x0cfdb 0x00gdt_end:ReadPoint dw 0 ; Memory Position for Read operationSectorToRead dw 0 ; Sector will be readDataSector dw 0 ; Data Sector beginSector dw 0 ; Sector in memoryRootPoint dw 0TIMES 0x1FE-($-$$) db 0ENDSTAMP dw 0xAA55
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -