📄 mbrbm.s
字号:
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
%ENDIF
CR EQU 0x0D
LF EQU 0x0A
; PC AT bios
; video
VIDEO EQU 0x10 ; bios video interrupt
PUTC EQU 0x0E ; put character
CNTRL EQU 0x0007 ; control word
; disc
DISC EQU 0x13 ; bios disc interrupt
READ1 EQU 0x0201 ; bios read, 1 sector
WRITE1 EQU 0x0301 ; bios write, 1 sector
DRIVE0 EQU 0x80 ; bios hard disc drive 0 number
; keyboard
KEYB EQU 0x16 ; bios keyboard interrupt
KEYBST EQU 0x01 ; bios keyboard status
KEYBK EQU 0x00 ; bios keyboard key
; time
RTIME EQU 0x1A ; bios time interrupt
GETTIME EQU 0x00 ; get time
READDT EQU 0x04 ; bios read date
; RealTimeClock
RTCPORT EQU 70 ; rtc port
RTCPIO EQU 0x71 ; rtc ioadr
RTCREAD EQU 0x80 ; read request
RTCDAY EQU 7 ; day offset
RTCMONTH EQU 8 ; month offset
RTCYEAR EQU 9 ; year offset
RTCCENTURY EQU 50 ; century offset
; MasterBootBlock
MAGIC EQU 0xAA55 ; hard disc boot block magic word
SDEV EQU 0x80 ; boot partition flag
MBOOTL EQU 512 ; boot block length
NPARTN EQU 4 ; max. number of partitions
PARTL EQU 16 ; partition table entry length
NPARTL EQU PARTL*NPARTN ; partition table length
BCODEL EQU MBOOTL-NPARTL-2 ; max. length of boot code
PARTAB EQU BCODEL ; position of partition table
SIGNUM EQU MBOOTL-2 ; position of signum magic word
P_BOOT EQU 0 ; boot flag
P_HEAD EQU 1 ; partition start head
P_SEC EQU 2 ; partition start sector
P_CYL EQU 3 ; partition start cylinder
P_SYS EQU 4 ; partition start cylinder
P_BASE EQU 8 ; partition start block
P_SIZE EQU 12 ; partition block length
INVPART EQU '?' ; invalid partition
LOWPART EQU 0 ; low partition
HIGPART EQU 7 ; high partition
; locations of mboot in memory
LOADLOC EQU 0x7C00 ; boot block load location in memory
COPYLOC EQU 0x0600 ; copy location of boot block
COPYLOCSHR4 EQU 0x0060 ; copy location of boot block shifted 4r
LOADADR EQU LOADLOC-COPYLOC ; load location in segment
MBRBR0:
; master boot block code
ORG 0 ; for .BIN file
CLI ; clear interrupts
; set data segment pointers to COPYLOC for org 0
MOV AX, COPYLOCSHR4 ; shift segment adress
MOV SS, AX ; set all segments
MOV DS, AX ; COPYLOC -> offset 0
MOV ES, AX ; LOADLOC -> offset LOADADR
; set SP to use below load address
MOV SP, LOADADR ; enough stack below load area
STI
CLD
; copy boot block to COPYLOC
MOV SI, LOADADR ; copy block to get load area free
XOR DI, DI ; for operation system bootstrap
MOV CX, MBOOTL
REP MOVSB
; jump far to copied code
JMP 0:COPYLOC+JMP_TO_COPY ; jump far over jmp
JMP_TO_COPY:
; display logo and headline
MOV SI, LOGO ; logo
CALL PUTS
; analyse drives
CALL ANALYSE_TABLE ; analyse first hard disc
INC BYTE [DRIVE] ; next hard disc
CALL READ_TABLE ; read partition table
OR AH, AH ; read ok?
JNZ ASK ; 2. disk installed
CALL ANALYSE_TABLE ; analyse second hard disc
ASK:
MOV SI, PROMPT ; issue prompt
JMP GET_PART ; jump over error message
; data
WAITC EQU 300 ; wait counter for mboot
LOGO:
DB 'mbrbm2',CR,LF ; logo string
HEAD:
DB 'Drv Part SysId 1GB' ; partition table headline
CRLF:
DB CR,LF,0 ; carriage return, line feed
PARTITION: ; partition string
DRIVE: ; drive number ascii 0..1
DB '0 '
PART:
DB '0' ; partition number ascii 0..7
ACTIND:
DB 'B ' ; active partition indicator
SYSID:
DB '0 ' ; system identification number ascii
MEGBYTE:
DB '0',CR,LF,0 ; partition size in megbytes ascii
ACTIVE:
DB INVPART ; init active partition to unvalid
DB CR,LF,0
INVTABLE:
DB 'Inv',CR,LF ; error message invalid partition
PROMPT:
DB 'Boot?',0 ; load partition prompt string
; read boot block
READ_TABLE:
MOV CX, 00001 ; cyl 0, sect 1
MOV DX, DRIVE0-'0' ; head 0
ADD DL, [DRIVE] ; drive 0 or 1
CALL READ_DISC
MOV SI, LOADADR+PARTAB ; copy partition table
MOV DI, PART_TAB ; to copy area for save
MOV CX, NPARTL
REP MOVSB
RET
; read from disc via bios, return code AH
READ_DISC:
MOV AX, READ1 ; read one sector
MOV BX, LOADADR ; into load area
INT DISC
JB READ_DISK_RET ; disc error
CMP WORD [LOADADR+SIGNUM], MAGIC
JZ READ_DISK_RET ; no valid partition table
MOV AH, 0xFF
READ_DISK_RET:
RET
; display *SI -> display
PUTS:
NEXT_CHAR:
LODSB
OR AL, AL ; last char ='\0'?
JZ NEXT_CHAR_RET
MOV AH, PUTC ; next char
MOV BX, CNTRL ; control word tty emulation
PUSH SI
INT VIDEO
POP SI
JMP NEXT_CHAR
; convert dec -> ascii, AX -> [--DI], max 2550!
CONVERT:
MOV BH, ' ' ; overwrite five chars
MOV [DI-4], BH ; with blanc
MOV [DI-3], BH ; with blanc
MOV [DI-2], BH ; with blanc
MOV [DI-1], BH ; with blanc
MOV CH, 10 ; decimal base
NEXT_DIGIT:
DIV CH ; next modulu
ADD AH, '0' ; ascii conversion
MOV [DI], AH ; put in string
DEC DI ; next position
XOR AH, AH ; clear high byte
OR AL, AL ; was last digit?
JNZ NEXT_DIGIT
NEXT_CHAR_RET:
RET
; analyse partition table
ANALYSE_TABLE:
MOV BP, PART_TAB ; si = *partititon table
MOV CX, NPARTN ; search active partition 0..3
NEXT_PART:
PUSH CX
MOV AL, ' ' ; default not active
TEST BYTE [BP], SDEV ; partition active?
JZ NOT_ACTIVE
MOV AL, [ACTIVE] ; active partition already found?
XOR AL, INVPART ; no more marked invalid
JNZ SCND_ACTIVE ; second active found
MOV AL, [PART] ; remember active partition
MOV [ACTIVE], AL
SCND_ACTIVE:
MOV AL, 'B' ; mark with 'B'
NOT_ACTIVE:
MOV [ACTIND], AL ; set active indicator
MOV AL, [BP+P_SYS] ; display system identification
XOR AH, AH
MOV DI, SYSID
CALL CONVERT
MOV AX, [BP+P_SIZE+2] ; display partition size in GB
SAR AX, 5
INC AX ; round up gb
MOV DI, MEGBYTE
CALL CONVERT
MOV SI, PARTITION ; display partition information
CALL PUTS
ADD BP, BYTE PARTL ; next partition
INC BYTE [PART]
POP CX
LOOP NEXT_PART
RET
; invalid message
INVALID:
MOV SI, INVTABLE ; issue error message
; get partition
GET_PART:
CALL PUTS
; wait for key or timeout
WAIT_KEY:
XOR AH, AH
INT RTIME
MOV BX, DX ; init wait counter
ADD BX, BYTE WAITC
KEY_PRESSED:
MOV AH, KEYBST ; wait for key pressed or timeout
INT KEYB
JNZ GET_CHAR ; key pressed?
XOR AH, AH
INT RTIME
CMP BX, DX ; timeout?
JG KEY_PRESSED
JMP CHECK ; timeout, load active partition
; get pressed key from buffer
GET_CHAR:
MOV AH, KEYBK ; get pressed key
INT KEYB
MOV [ACTIVE], AL ; remember active
; check partition validity
CHECK:
MOV SI, ACTIVE ; type boot partition
CALL PUTS
MOV AL, [ACTIVE] ; get active or pressed
SUB AL, '0' ; check partition number 0..7
JL INVALID
CMP AL, HIGPART
JG INVALID
MOV BYTE [DRIVE], '1' ; build drive number
CMP AL, 4 ; 0..3 drive 0, 4..7 drive 1
SBB BYTE [DRIVE], 0 ; drive number ascii
AND AX, 00003 ; partition number MOD 4
MOV CL, 4 ; partition number * PARTL
SHL AX, CL
ADD AX, PART_TAB ; build partition table entry adress
MOV BP, AX ; partition table entry adress
CALL READ_TABLE ; read partition table from drive
OR AH, AH ; read ok?
JNZ INVALID
; boot partition
BOOT_PART:
CMP [BP+P_SYS], AH ; partition empty?
JZ INVALID
MOV AL, [DRIVE] ; get first partition block for os boot
ADD AL, DRIVE0-'0' ; ascii -> 080
MOV [BP], AL ; build head, sector adress
MOV CX, [BP+P_SEC]
MOV DX, [BP]
CALL READ_DISC ; read operating system bootstrap
OR AH, AH ; read ok?
JNZ INVALID
; set proper environment for os boot
ADD BP, COPYLOC ; di, si, bp = partition table entry
MOV SI, BP ; nessessary? perhaps XENIX?
MOV DI, BP
; set segment pointers to 0
XOR AX, AX
MOV SS, AX
MOV DS, AX
MOV ES, AX
MOV SP, LOADLOC
MOV BX, SP
JMP 0:LOADLOC ; boot operation system via far jump
; into bootstrap
; data until end of block
VOLUMEID:
TIMES BCODEL-$+MBRBR0 DB 0xFF ; filler for VolumeID
PART_TAB:
TIMES NPARTL DB 0 ; partition table
SIG_NUM:
DW MAGIC ; magic word
; END-OF-MBRBM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -