📄 manager.asm
字号:
cmp ax, NUM_MENUS
jb @@boot_n_short
jmp @@wait_key
@@up:
cmp ACT_MENU, 0
jz @@cont2short
dec ACT_MENU
jmp @@cont2
@@down:
mov ax, NUM_MENUS
dec ax
jb @@cont2short
cmp ACT_MENU, ax
jnb @@cont2short
inc ACT_MENU
jmp @@cont2
@@home:
mov ACT_MENU, 0
jmp @@cont2
@@end:
mov ax, NUM_MENUS
dec ax
jb @@cont2short
mov ACT_MENU, ax
jmp @@cont2
@@space:
call SETUP_MENU
xor di, di
jmp @@while1
@@boot_a_short:
jmp @@boot_a
@@boot_d_short:
jmp @@boot_d
@@boot_n_short:
jmp @@boot_n
@@boot2short:
jmp @@boot
@@alt_boot2short:
jmp @@alt_boot
@@cont2short:
jmp @@cont2
@@boot_esc2short:
jmp @@boot_esc
@@hide_all:
mov bx, 0
call CHECK_PASSWORD
jc @@cont2short
mov ax, ACT_MENU
push ax
mov ax, -1
mov ACT_MENU, ax
mov dl, 0
call PREP_BOOT_SECT_X
pop ax
mov ACT_MENU, ax
jnc @@break_out_short
jmp @@cont2
@@break_out_short:
jmp @@break_out
@@alt_boot:
mov ALT_ENTER, 1
jmp @@boot
@@boot_a:
mov bx, 0
call CHECK_PASSWORD
jc @@cont2short
mov dl, 0
call PREP_BOOT_SECT_X
jnc @@break_out_short
jmp @@cont2
@@boot_d:
mov bx, 0
call CHECK_PASSWORD
jc @@cont2short
mov dl, DISK
inc dl
call PREP_BOOT_SECT_X
jnc @@break_out
jmp @@cont2
@@boot_n:
mov ACT_MENU, ax
@@boot:
cmp NUM_MENUS, 0
je @@boot_a
mov bx, ACT_MENU
shl bx, 1
mov ax, MENU_PTR[bx]
lea bx, menu
sub ax, bx
mov bl, SIZE adv_menu_rec
div bl
mov adv_act_menu, al
@@boot_esc:
cmp NUM_MENUS, 0
je @@boot_a
mov bx, ACT_MENU
shl bx, 1
mov bx, MENU_PTR[bx]
push bx
call CHECK_PASSWORD
pop bx
jc @@cont2
cmp [bx].m_type, M_BOOT_PART
je @@boot_type_part
cmp [bx].m_type, M_BOOT_NEXT_HD
je @@boot_type_next_hd
cmp [bx].m_type, M_BOOT_FLOPPY
je @@boot_type_floppy
jmp @@cont2 ; We dont know what it is - ingnoring
@@boot_type_part:
call PREP_BOOT_SECT
jnc @@break_out
jmp @@cont2
@@boot_type_next_hd:
mov dl, DISK
inc dl
call PREP_BOOT_SECT_X
jc @@cont2
call FILL_KEYB_BUFFER
jmp @@break_out
@@boot_type_floppy:
mov dl, 0
call PREP_BOOT_SECT_X
jc @@cont2
call FILL_KEYB_BUFFER
jmp @@break_out
@@cont2:
mov di, 1
jmp @@while1
@@break_out:
ret
MAIN_MENU ENDP
;
;
CHECK_PASSWORD PROC NEAR
;
; Input: bx - pointer to ActiveMenu, or 0 if no menu
;
; Output: CF - clear if password validated
; CF - set if user cannot proceed
;
PUSH_REGS
cmp PASS_VALIDATED, 1
je @@valid
cmp bx, 0
jz @@do_check
test [bx].m_options, M_OPT_PASSW
jz @@valid ; This menu item needs no validation
@@do_check:
cmp adv_password, 0
je @@valid ; No master password set
call GET_PASSWORD
cmp ax, adv_password
je @@valid
@@invalid:
lea si, MesgPasswordInvalid
call SHOW_ERROR
stc
jmp @@end
@@valid:
mov PASS_VALIDATED, 1
clc
@@end:
POP_REGS
ret
CHECK_PASSWORD ENDP
;
;
;
PREP_BOOT_SECT PROC NEAR
;
; Output: CF - set if error
;
PUSH_REGS
call MAKE_PART_TAB
mov di, ACT_MBR_REC
mov bx, Offset OS_BOOT_SECT
mov dx, [di]
mov cx, [di+2]
call READ_SECT
jc @@err_read
mov di, Offset OS_BOOT_SECT
mov cx, 512
mov al, 0
repe
scasb
jcxz @@sect_empty
call COMPARE_MBR_SECT ; did we change boot sector
jnc @@not_changed ; no need to save
mov bx, Offset MBR_SECT
xor dx, dx
xor ax, ax
mov cx, 1
call WRITE_N_SECT
jc @@err_save
@@not_changed:
call FILL_KEYB_BUFFER
clc
jmp @@end
@@err_read:
lea si, MesgErrorRead
call SHOW_ERROR
stc
jmp @@end
@@sect_empty:
lea si, MesgBootInvalid
call SHOW_ERROR
stc
jmp @@end
@@err_save:
lea si, MesgErrorSave
call SHOW_ERROR
stc
@@end:
POP_REGS
ret
PREP_BOOT_SECT ENDP
;
;
PREP_BOOT_SECT_X PROC NEAR
;
; Input: DL - Disk number
; Output: CF - set if error
;
PUSH_REGS
push dx
call MAKE_PART_TAB
pop dx
lea di, FD_PARAMS
mov cx, 1
mov dh, 0
mov [di], dx
mov [di+2],cx
mov ACT_MBR_REC, di
mov bx, Offset OS_BOOT_SECT
call READ_SECT
jc @@err_read
call COMPARE_MBR_SECT ; did we change boot sector
jnc @@not_changed ; no need to save
mov bx, Offset MBR_SECT
xor dx, dx
xor ax, ax
mov cx, 1
call WRITE_N_SECT
jc @@err_save
@@not_changed:
clc
jmp @@end
@@err_read:
lea si, MesgErrorRead
call SHOW_ERROR
stc
jmp @@end
@@err_save:
lea si, MesgErrorSave
call SHOW_ERROR
clc ; We still want to boot from A: (or D:)
@@end:
POP_REGS
ret
PREP_BOOT_SECT_X ENDP
;
;
;
BACKUP_MBR_SECT PROC NEAR
push cx
push si
push di
mov cx, 512
mov si, Offset MBR_SECT
mov di, Offset MBR_SECT_BAK
rep
movsb
pop di
pop si
pop cx
ret
BACKUP_MBR_SECT ENDP
;
;
;
COMPARE_MBR_SECT PROC NEAR
;
; CF - set if boot sector was changed
;
push cx
push si
push di
mov cx, 512
mov si, Offset MBR_SECT
mov di, Offset MBR_SECT_BAK
repe
cmpsb
je @@equal
stc
jmp @@end
@@equal:
clc
@@end:
pop di
pop si
pop cx
ret
COMPARE_MBR_SECT ENDP
;
;
;
MAKE_PART_TAB PROC NEAR
;
; Input: ACT_MENU
;
; Output: ACT_MBR_REC - points to active mbr_part_rec
;
push bp
mov ACT_PART_PTR, 0
;
; Clearing PART_TMP and MBR part_rec
;
xor ax, ax
lea di, PART_TMP
mov cx, SIZE PART_TMP
rep
stosb
lea di, PART_TMP2
mov cx, SIZE PART_TMP2
rep
stosb
lea di, part_rec
mov cx, SIZE part_rec
rep
stosb
;
; Lets find last partition
;
xor bp, bp
xor si, si
lea di, part
mov cx, MAX_PART_ROWS
mov bx, di
@@next_step:
mov ax, Word Ptr [di].p_num_sect
or ax, Word Ptr [di].p_num_sect+2
jz @@last_found
add di, SIZE adv_part_rec
loop @@next_step
@@last_found:
cmp bx, di
je @@show_one_je_short
sub di, SIZE adv_part_rec
cmp NUM_MENUS, 0
@@show_one_je_short:
je @@show_one
mov bx, ACT_MENU
cmp bx, -1
je @@show_unused
shl bx, 1
mov si, MENU_PTR[bx]
mov al, [si].m_show
mov si, PART_PTR[bx]
mov ACT_PART_PTR, si
cmp si, 0
jne @@not_zero
xor di, di ; No partition associated with menu
xor bp, bp ; so we will hide everything
jmp @@eval_part
@@not_zero:
;
; SI -> active partition
; DI -> last partition
; AL - representation mode
;
cmp al, SHOW_NEXT
je @@show_next
cmp al, SHOW_PREV
je @@show_prev
cmp al, SHOW_LAST
je @@show_last
cmp al, SHOW_LAST3
je @@show_last3
jmp @@show_one
@@show_prev:
lea bx, part
cmp bx, si
je @@show_one
mov di, si
sub si, SIZE adv_part_rec
jmp @@eval_part
@@show_next:
cmp si, di
je @@show_one
mov di, si
add di, SIZE adv_part_rec
jmp @@eval_part
@@show_last:
cmp si, di
jne @@eval_part
jmp @@show_one
@@show_last3:
push di
sub di, SIZE adv_part_rec
sub di, SIZE adv_part_rec
cmp di, Offset part
jnb @@now_check_si
pop di
jmp @@show_last
@@now_check_si:
cmp si, di
pop di
jb @@show_last
mov bp, di
sub di, SIZE adv_part_rec
mov si, di
sub si, SIZE adv_part_rec
jmp @@eval_part
@@show_one:
xor di, di
jmp @@eval_part
@@show_unused: ; Show first unused space
xor di, di ; greater than 63 sectors
lea si, part
mov cx, MAX_PART_ROWS
@@unused_next:
cmp [si].p_os_id, 0
jne @@unused_cont
cmp Word Ptr [si].p_num_sect+2, 0
jne @@eval_part
cmp Word Ptr [si].p_num_sect, 63
ja @@eval_part
@@unused_cont:
add si, SIZE adv_part_rec
loop @@unused_next
xor si, si ; didn't find any
@@eval_part:
;
; SI -> first partition, or zero
; DI -> second partition, or zero
; BP -> third partition, or zero
;
lea bx, part
mov ax, Word Ptr [bx].p_rel_sect
mov dx, Word Ptr [bx].p_rel_sect+2
lea bx, PART_TMP
mov cx, 0
mov LAST_PART, 0
@@next_row:
cmp si, 0
jne @@check_gap
jmp @@tail
@@check_gap:
cmp Word Ptr [si].p_rel_sect+2, dx
ja @@fill_gap
cmp Word Ptr [si].p_rel_sect, ax
ja @@fill_gap
mov ax, [si].p_os_id
mov [bx].p_os_id, ax
mov al, [si].p_orig_row
mov [bx].p_orig_row, al
mov al, 0
cmp si, ACT_PART_PTR
jne @@not_active
mov al, DISK
@@not_active:
mov [bx].p_tag, al
mov ax, Word Ptr [si].p_rel_sect
mov dx, Word Ptr [si].p_rel_sect+2
mov Word Ptr [bx].p_rel_sect, ax
mov Word Ptr [bx].p_rel_sect+2, dx
mov ax, Word Ptr [si].p_num_sect
mov dx, Word Ptr [si].p_num_sect+2
mov Word Ptr [bx].p_num_sect, ax
mov Word Ptr [bx].p_num_sect+2, dx
add ax, Word Ptr [si].p_rel_sect
adc dx, Word Ptr [si].p_rel_sect+2
mov LAST_PART, si
mov si, di
mov di, bp
mov bp, 0
add bx, SIZE adv_part_rec
inc cx
cmp cx, 4
je @@table_filled_short
jmp @@next_row
@@table_filled_short:
jmp @@table_filled
@@fill_gap:
test adv_options, ADV_OPT_IGN_UNUSED
jz @@go_fill_gap
cmp LAST_PART, 0
je @@go_fill_gap
push si
sub si, SIZE adv_part_rec
cmp si, LAST_PART
pop si
jne @@go_fill_gap
mov ax, Word Ptr [si].p_rel_sect
mov dx, Word Ptr [si].p_rel_sect+2
jmp @@next_row
@@go_fill_gap:
mov [bx].p_os_id, OS_HIDDEN
mov [bx].p_tag, 0
mov [bx].p_orig_row, 0
mov Word Ptr [bx].p_rel_sect, ax
mov Word Ptr [bx].p_rel_sect+2, dx
mov ax, Word Ptr [si].p_rel_sect
mov dx, Word Ptr [si].p_rel_sect+2
sub ax, Word Ptr [bx].p_rel_sect
sbb dx, Word Ptr [bx].p_rel_sect+2
mov Word Ptr [bx].p_num_sect, ax
mov Word Ptr [bx].p_num_sect+2, dx
mov ax, Word Ptr [si].p_rel_sect
mov dx, Word Ptr [si].p_rel_sect+2
add bx, SIZE adv_part_rec
inc cx
cmp cx, 4
je @@table_filled
jmp @@next_row
@@tail:
mov Word Ptr [bx].p_rel_sect, ax
mov Word Ptr [bx].p_rel_sect+2, dx
mov ax, SECT_PER_CYL
mov dx, DISK_NUM_CYLS
mul dx
sub ax, Word Ptr [bx].p_rel_sect
sbb dx, Word Ptr [bx].p_rel_sect+2
mov Word Ptr [bx].p_num_sect, ax
mov Word Ptr [bx].p_num_sect+2, dx
or ax, dx ; is part size zero
jz @@table_filled
mov [bx].p_os_id, OS_HIDDEN
mov [bx].p_tag, 0
mov [bx].p_orig_row, 0
@@table_filled:
;
; Now lets make sure that active partition occupies
; slot in partition table from which it was taken
;
@@check_locations:
mov cx, 4
lea si, PART_TMP
@@check_next_part:
mov ah, 0
mov al, [si].p_orig_row
cmp al, 0
jne @@row_is_not_0
add si, SIZE adv_part_rec
loop @@check_next_part
jmp @@nothing_to_move
@@row_is_not_0:
dec ax
mov bl, SIZE adv_part_rec
mul bl
lea bx, PART_TMP
add bx, ax
cmp bx, si
je @@part_in_place
push bx ; that's where partition supposed to be
push si ; that's where it is
lea di, PART_TMP2
mov cx, SIZE adv_part_rec
rep ; moving partition to PART_TMP2
movsb
pop di
pop si
push si
mov cx, SIZE adv_part_rec
rep ; moving whatever occupies place out
movsb
pop di
push di
lea si, PART_TMP2
mov cx, SIZE adv_part_rec
rep ; moving partition to its proper place
movsb
pop si
@@part_in_place:
mov [si].p_orig_row, 0 ; so we won't move it again
jmp @@check_locations
@@nothing_to_move:
;
; Converting temporary structures
; into records in the partition table
;
mov cx, 4
lea si, PART_TMP
lea di, part_rec
@@next_part_rec:
push cx
push si
push di
cmp [si].p_os_id, 0
je @@cont
mov ax, Word Ptr [si].p_rel_sect
mov dx, Word Ptr [si].p_rel_sect+2
push dx
push ax
call REL_SECT_TO_CHS
mov dl, [si].p_tag
or dl, dl
jz @@part_not_active
mov ACT_MBR_REC, di
@@part_not_active:
mov ax, dx
stosw
mov ax, cx
stosw
pop ax
pop dx
add ax, Word Ptr [si].p_num_sect
adc dx, Word Ptr [si].p_num_sect+2
sub ax, 1
sbb dx, 0
call REL_SECT_TO_CHS
mov dl, Byte Ptr [si].p_os_id+1
mov ax, dx
stosw
mov ax, cx
stosw
lea si, [si].p_rel_sect
movsw
movsw
movsw
movsw
@@cont:
pop di
pop si
add si, SIZE adv_part_rec
add di, SIZE mbr_part_rec
pop cx
loop @@next_part_rec
@@end:
pop bp
ret
MAKE_PART_TAB ENDP
;
;
;
IMPORT_NEW_PART PROC NEAR
push bp
mov IMPORTED_FLAG, 0
mov cx, 1
lea si, part_rec
@@next_mbr_part:
push cx
cmp [si].b_os_id, 0 ; Unused - ignore it
je @@mbr_cont_short
cmp [si].b_os_id, 0FFh ; Hidden - ignore it
je @@mbr_cont_short
jmp @@test_part
@@mbr_cont_short:
jmp @@mbr_cont
@@test_part:
mov ax, Word Ptr [si].b_rel_sect
mov dx, Word Ptr [si].b_rel_sect+2
push ax
or ax, dx
pop ax
jz @@mbr_cont ; Empty - ignore it
mov cx, MAX_PART_ROWS
lea di, part
@@next_part:
cmp ax, Word Ptr [di].p_rel_sect
jne @@part_cont
cmp dx, Word Ptr [di].p_rel_sect+2
jne @@part_cont
; Relative sectors matched
mov ax, Word Ptr [si].b_num_sect
mov dx, Word Ptr [si].b_num_sect+2
cmp ax, Word Ptr [di].p_num_sect
jne @@import_part
cmp dx, Word Ptr [di].p_num_sect+2
jne @@import_part
; Number of sectors also same
jmp @@check_id
@@part_cont:
add di, SIZE adv_part_rec
loop @@next_part
jmp @@import_part
@@check_id:
mov ax, [di].p_os_id
cmp ax, OS_ADV
je @@import_part
cmp ah, [si].b_os_id
je @@mbr_cont
mov ah, [si].b_os_id
mov al, 0
mov [di].p_os_id, ax
mov IMPORTED_FLAG, 1
jmp @@mbr_cont
@@import_part:
mov cx, MAX_PART_ROWS
lea di, part + SIZE part
@@step_back:
sub di, SIZE adv_part_rec
cmp [di].p_os_id, 0
je @@copy_part
loop @@step_back
jmp @@mbr_cont
@@copy_part:
mov ah, [si].b_os_id
mov al, 0
stosw ; p_os_id
mov al, 0
stosb ; p_tag
pop ax
push ax
stosb ; p_orig_row
xor ax, ax
stosw ; reserved
stosw ; reserved
push si
add si, 8
movsw ; rel_sect
movsw
movsw ; num_sect
movsw
pop si
mov IMPORTED_FLAG, 10h
@@mbr_cont:
add si, SIZE mbr_part_rec
pop cx
inc cx
cmp cx, 5
je @@break_out
jmp @@next_mbr_part
@@break_out:
cmp IMPORTED_FLAG, 0
je @@end
mov ax, Word Ptr ADV_REL_SECT
mov dx, Word Ptr ADV_REL_SECT+2
mov bx, ADV_DATA_ADDR
mov cx, ADV_DATA_SECT
call WRITE_N_SECT
jnc @@end
lea si, MesgErrorSaveAdv
call SHOW_ERROR
@@end:
pop bp
ret
IMPORT_NEW_PART ENDP
;
;
;
SPRINTF_MENU PROC NEAR
;
; Input: AX - Menu number
; Output: TMP - Filled with menu line
;
PUSH_REGS
push ax
inc ax
lea si, TMP
mov cx, 3
call SPRINTF_INT
lea di, TMP+3
mov al, ' '
stosb
stosb
mov cx, 30
pop bx
shl bx, 1
mov si, MENU_PTR[bx]
lea si, [si].m_name
@@char:
lodsb
or al, al
jz @@break
stosb
loop @@char
@@break:
mov al, ' '
jcxz @@no_spaces
@@space:
rep
stosb
@@no_spaces:
stosb
mov si, PART_PTR[bx]
cmp si, 0
je @@no_part
mov ax, Word Ptr [si].p_num_sect
mov dx, Word Ptr [si].p_num_sect+2
mov cl, 11
shr ax, cl
mov cl, 5
shl dx, cl
or ax, dx
mov cx, 6
mov si, di
call SPRINTF_INT
add di, 6
mov al, 'M'
stosb
mov al, ' '
stosb
jmp @@end
@@no_part:
mov cx, 8
mov al,' '
rep
stosb
@@end:
mov al, 0
stosb
POP_REGS
ret
SPRINTF_MENU ENDP
;
;
;
SPRINTF_INT PROC NEAR
;
; Input: AX - Integer to print
; CX - Field len
; DS:SI - String to fill
;
PUSH_REGS
mov di, cx
mov bx, 10
xor cx, cx
@@next:
xor dx, dx
div bx
push dx
inc cx
cmp ax, 0
jne @@next
mov bx, di
cmp cx, bx
jae @@digit
sub bx, cx
mov al, ' '
@@space:
mov [si], al
inc si
dec bx
jne @@space
@@digit:
pop ax
add ax, '0'
mov [si], al
inc si
dec cx
jne @@digit
xor ax, ax
mov [si], al
POP_REGS
ret
SPRINTF_INT ENDP
;
;
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -