免费下载应用软件、交流使用经验。

软件下载 经验交流 软件开发 专题论述 请君留言 网站介绍 休闲时光 返回主页
 
多系统启动软件的开发

作者:本人     来源:本站

    作者从1999年6月份开始到2000年5月份期间,曾专门研究了多系统启动选择软件的开发,编制了《ZERO多系统启动》程序。该程序存放在一张特制的软盘上,通过用这张软盘启动电脑,自动识别电脑硬盘中安装在独立分区中的不同操作系统,由用户选择需要进入哪个操作系统。该程序已经基本编制完毕,由后来工作紧张,加之从2001年下半年后提供免费空间的163.net中断了个人主页服务,失去了与广大网友交流的平台,故无法进一步完善该程序。
    现在WINDOWS系统几乎是一统天下,其中的boot.ini可以很方便地选择安装在任何分区中的操作系统,故《ZERO多系统启动》程序存在的意义不是很大。但作为一种实验、或为了了解电脑启动的过程,本程序还是有一定的意义。现在将此程序的代码奉献给广大网友。 
     

2000.05.02版

;**********************************************************
;*                                                        *
;*   多操作系统启动选择程序 ZEROLOAD.ASM--软盘引导程序      *
;*                                                        *
;*      编制:胡家峻  1999.8-2000.4  江西.宜春   ?        *
;*                 TEL:0795-3245707                       *
;*                 http://softroom.163.net                *
;*                 E-mail:softroom@163.net                *
;**********************************************************
code     segment             ;汇编程序开始
         assume cs:code,es:code
         org 100h
begin    proc far            ;程序开始
;屏幕初始显示
         xor ax,ax
         push ax             ;将段指针指00H
         pop ds
         push ax
         pop es
         mov ax,600h
         mov bh,17h          ;屏幕属性(或bh=01)
         xor cx,cx           ;左上角y,x座标
         mov dx,184fh        ;右下角y,x座标
         int 10h             ;清蓝色屏幕
         mov bx,offset zero1 ;取数据串地址
         mov ax,1fdbh        ;背景=1,前景=e,字符=<空格>
         mov cx,26h          ;共38项
         call redisp         ;调用重复显示子程序
         mov bx,offset zero2 ;ES:BP=源串的段:位移
         call disp2          ;显示"V 0.12"
         mov bx,offset zero3 ;ES:BP=源串的段:位移
         call disp2          ;显示"Copyright by hujiajun"
         mov bx,offset zero4 ;ES:BP=源串的段:位移
         call disp2          ;显示"http://softroom.soim.com"
         mov bx,offset zero5 ;ES:BP=源串的段:位移
         call disp2          ;显示"E-mail:softroom@163.net"
         mov bx,offset zero6 ;ES:BP=源串的段:位移
         call disp2          ;显示"Welcome to ZERO"
         mov bx,offset zero7 ;ES:BP=源串的段:位移
         call disp2          ;显示"2000.04"
         mov al,1eh
         mov es:winc,al
         mov ax,3fc4h        ;重复62次,显示单横线
         mov dx,908h
         call disp3
         mov ax,9dbh
         mov dx,es:disx
         call disp3          ;显示9个'  '
         mov ax,3fc4h
         mov dx,1608h
         call disp3          ;在23行显示单横线
         mov al,es:cal0
         add al,30h
         mov ah,1
         mov dx,172dh        ;显示剩余秒数
         call disp3
;屏幕显示完毕,开始读引导扇区及分区ID号
         mov bx,7c00h        ;将硬盘分区数据读入7C00H处
         mov ax,201h
         mov cx,1
         mov dx,80h
         int 13h             ;读第一硬盘引导扇区
         mov bx,7dc2h        ;设置分区数据指针
         xor cl,cl
         mov dx,offset sele1 ;ID保存地址
b1:      mov al,es:[bx]      ;读出分区ID号
         cmp al,0
         jz b3               ;空分区转移
         xchg dx,bx
         mov es:[bx],al      ;保存分区ID
         inc bx
         inc cl
         xchg dx,bx
         mov al,es:[bx-4]    ;取活动标志
         cmp al,80h
         jnz b2
         mov es:sele0,cl     ;记录活动分区号
         mov es:men1,cl      ;设置菜单默认项
b2:      add bx,10h
         cmp cl,4
         jnz b1              ;读下一分区数据
;分区系统ID及活动分区标志读完,计算显示菜单的总项数
b3:      mov al,3            ;加基本项
         add al,cl
         mov es:men0,al      ;保存总菜单项数
;置固定菜单选项的代号
         mov al,11h
         mov bx,dx
         mov es:[bx],al      ;置Setup ZERO 菜单代号
         inc al
         inc bx
         mov es:[bx],al      ;置Reple old system 菜单代号
         inc al
         inc bx
         mov es:[bx],al      ;置Reple ZERO 菜单代号
;取菜单项总数,准备将系统的ID号转换成菜单显示的代号
         mov cl,es:men0
         dec cl
         dec cl
         dec cl
         mov bx,offset sele1 ;分区菜单号开始地址
         mov dx,offset idcode ;码表开始地址
b4:      mov al,es:[bx]      ;读ID号
         xchg bx,dx
         xlat                ;换码
         xchg bx,dx
         mov es:[bx],al      ;保存菜单显示代号
         inc bx
         dec cl
         jnz b4
; 开始显示菜单
bb0:     mov ch,1            ;设当前菜单显示项
         mov cl,es:men0      ;取总显示项
         mov bx,offset sele1 ;取显示代号地址
         mov dx,offset menu  ;取菜单字符起始地址
beg5:    push bx             ;ch=当前显示的菜单项序号
         push cx             ;cl=显示的菜单项总数
         push dx             ;bx=菜单显示序号开始地址
         xor ah,ah           ;dx=菜单显示字符开始地址
         mov al,es:[bx]      ;取当前显示的序号
         mov cl,4            ;乘以16(左移4位)
         sal ax,cl
         add ax,dx           ;计算出当前菜单显示字符串地址
         mov bp,ax
         mov al,ch           ;取当前显示的菜单条号
         add al,0ah          ;加上起始行号
         mov dh,al           ;当前显示的行号
         mov dl,20h          ;当前显示的列号
         mov cx,10h          ;显示的字符串长度(固定为16个字)
         mov bx,17h          ;显示的页号及属性
         mov ax,1300h
         int 10h             ;显示当前菜单条
         pop dx
         pop cx
         pop bx
         inc bx              ;下一菜单条显示序号
         inc ch              ;下一菜单项号
         dec cl
         jnz beg5            ;继续显示下一菜单条
;菜单条显示完毕, 置定时器中断1Ch,准备计时(待以后修改)
         mov ax,[0070h]      ;取原中断入口数据
         mov ds:int1c0,ax    ;保存原中断
         mov ax,[0072h]
         mov ds:int1c1,ax
         mov ax,0e95eh       ;置中断向量jmp 入口(此处要修改)
         mov es:[0070h],ax
         mov ax,900bh
         mov es:[0072h],ax
         even
menu0:   call disp1          ;显示当前菜单
me1:     mov ah,1
         int 16h             ;检测键盘
         jnz me2             ;有键按下,跳转
         cmp es:chk,1
         jz me1             ;已经有键按下过, 但本次未按键
;检查计时, 定时无按键即自动选择原活动分区(前次选择的分区)
         cmp es:cal1,12h
         jb me1              ;未满一秒,跳转
         mov dx,es:disx      ;取行列号(dh=行,dl=列)
         inc dx
         mov es:disx,dx      ;保存行,列号
         mov ax,920h
         mov bl,1eh          ;蓝底黄字
         mov es:winc,bl      ;用空格覆盖进度条
         call disp3
         mov al,es:cal0
         cmp al,0
         jz m20
         dec al
         mov al,es:cal0
         add al,30h
         mov ah,1
         mov dx,172dh        ;显示剩余秒数
         call disp3
         cmp dl,2dh
         jnz me1             ;继续检测按键
         jmp menu6           ;等待时间已到,跳转启动默认分区
         even
;处理按键
me2:     cmp es:chk,1
         jz me3              ;已经按过键
         mov ax,ds:int1c0
         mov ds:[0070h],ax
         mov ax,ds:int1c1
         mov ds:[0072h],ax
         pop es
;有键按下, 停止自动计时, 恢复原中断
m20:     mov al,1
         mov es:chk,al       ;置已按键标志
me3:     xor ah,ah           ;清键盘缓冲区
         int 16h
         push ax
         call disp1          ;当前菜单条反相显示
         pop ax              ;恢复键码
         cmp ah,15
         jnz menu3           ;非TAB键转移
;菜单光条下移处理
menu1:   mov al,es:men1      ;取当前菜单条号
         cmp al,es:men0      ;与总菜单条数比较
         jnz menu2           ;不相等跳转
         xor al,al           ;当前菜单号置0
menu2:   inc al              ;菜单号增1
         mov es:men1,al      ;保存当前菜单号
         jmp menu0
         even
menu3:   cmp ah,80
         jz menu1            ;下移箭头转跳格键处理   
         cmp ah,77
         jz menu1            ;右移箭头转跳格键处理
         cmp ah,72
         jnz menu5           ;不是上移键, 跳转
;菜单条上移处理
menu31:  mov al,es:men1      ;上移键处理,取当前菜单号   
         dec al              ;菜单号减1
         cmp al,0
         jnz menu4
         mov al,es:men0      ;若是首行则转末行
menu4:   mov es:men1,al      ;保存当前菜单号
         jmp menu0
         even
menu5:   cmp ah,75
         jz menu31           ;左移键转上移处理
menu51:  cmp ah,57         
         jz menu6            ;空格键确认
         cmp ah,28
         jz menu6            ;回车键确认
         jmp menu0
         even
;确认选中处理
menu6:   mov bx,offset sele0 ;取菜单条号起始地址         
         mov al,es:men1      ;取当前菜单项号
         xor ah,ah
         add ax,bx           ;计算当前菜单条号地址
         mov bx,ax
         mov al,es:[bx]      ;取当前菜单条的代码
         cmp al,11h
         jnz menu62
;选中了Setup ZRRO 0.10
         mov bx,offset mess1 ;显示数据地址
         mov al,20h          ;显示属性为绿底黑字
         call win            ;调窗口子程序
         jc menu61           ;不安装,跳转
         call setup0         ;调用安装子程序
         jc menu61           ;安装不成功, 转菜单
         mov bx,offset mess6 ;取安装完成显示信息地址
         jnc menu65          ;安装成功, 显示信息后重新启动
         mov bx,offset messe ;取安装失败显示信息地址
menu60:  mov al,30h
         call win
menu61:  jmp menu0           ;继续显示菜单
         even
menu62:  jnb menu7
;选中的菜单条是不能启动的分区(代号小于11H),警告处理
         mov bx,offset mess8 ;显示数据地址
         mov al,47h          ;显示属性为红底白字
         call win            ;调窗口子程序
         jmp menu0           ;转菜单
         even
;安装或恢复ZERO系统完成,重新启动计算机
menu65:  mov al,30h          ;置青底黑字显示
         call win            ;调用窗口显示子程序
         int 19h             ;重新启动计算机
;继续判断按键
menu7:   cmp al,12h          ;选中了恢复原系统选项
         jnz menu8
         mov bx,offset mess3 ;显示数据地址
         mov al,47h          ;显示属性为红底白字
         call win            ;调窗口子程序
         jc menu61           ;不恢复,跳转
         call resa           ;调恢复模块
         jc menu70
         mov bx,offset messb ;恢复成功
         jmp menu65
         even
menu70:  mov bx,offset messf
         jmp menu60
         even
menu8:   cmp al,13h          ;选中了恢复ZERO系统选项
         jnz menu9
         mov bx,offset mess2 ;显示数据地址
         mov al,47h          ;显示属性为红底白字,临时
         call win            ;调窗口子程序,临时
         jc menu61
         call setup1         ;调恢复ZERO系统子程序
         jc menu70           ;恢复不成功, 转菜单
         mov bx,offset mess7 ;取恢复ZERO成功信息
         jmp menu65
;选中了可启动的分区
         even
menu9:   mov al,es:sele0     ;取当前活动分区号
         cmp al,es:men1      ;与当前菜单选项比较
         jz menu91           ;选中的分区本身就是活动分区
         mov cl,4            ;计算原活动分区号的地址
         sal al,cl
         xor ah,ah
         mov bx,7daeh
         push bx
         add bx,ax
         xor al,al
         mov es:[bx],al      ;取消原活动分区标志(置0)
         mov al,es:men1      ;计算选中的分区号地址
         mov cl,4
         sal al,cl
         xor ah,ah
         pop bx
         add bx,ax
         mov al,80h
         mov es:[bx],al      ;置新活动分区标志
         mov ax,301h
         mov bx,7c00h
         mov cx,1
         mov dx,80h
         int 13h             ;将引导扇区的内容写回硬盘
menu91:  mov al,es:men1      ;准备读选中分区的自举扇区
         mov cl,4
         sal al,cl           ;分区号乘以16后加基数
         xor ah,ah
         mov bx,7daeh
         add ax,bx          ;计算选中分区数据的起始地址
         mov bx,ax
         mov dx,es:[bx]     ;取磁盘及柱面号
         mov cx,es:[bx+2]   ;取磁道及扇区号
         mov bx,7c00h
         mov ax,201h
         int 13h            ;读分区自举扇区数据
         jmp 0:7c00h        ;跳转执行分区自举程序
         db 0
         db 0
         db 0
begin    endp
         even
redisp   proc near           ;重复显示子程序
;al=要显示的字符码,ah=显示属性
re0:     push cx             ;写入的项数
         mov dx,es:[bx]      ;取列号,行号
         inc bx
         inc bx
         push bx             ;保存数据指针
         push ax             ;保存字符及属性
         xor bh,bh
         mov ah,2
         int 10h             ;置光标位置
         pop ax              ;恢复字符及属性
         pop bx              ;恢复指针
         xor ch,ch
         mov cl,es:[bx]      ;取重复值
         inc bx
         push bx             ;保存指针
         push ax             ;保存字符及属性
         mov bl,ah           ;置写入属性
         xor bh,bh
         mov ah,0ah
         int 10h
         pop ax
         pop bx
         pop cx
         loop re0          ;显示下一项
         ret
redisp   endp
         even
disp1    proc near           ;菜单反相显示
         mov al,es:men1      ;取当前菜单项
         add al,0ah          ;加上起始行
         mov dh,al           ;行座标
         mov dl,1bh          ;列座标
disp10:  push dx             ;保存行列座标
         mov ah,2
         xor bh,bh
         int 10h             ;置光标位置
         mov ah,8
         xor bh,bh
         int 10h             ;取光标位置的字符和属性
         not ah              ;属性取反
         and ah,7fh          ;屏蔽高位
         mov bl,ah
         mov cx,1            ;长度1
         mov ah,9
         xor bh,bh
         int 10h             ;光标位置写入
         pop dx
         inc dl              ;列号加1
         cmp dl,34h
         jnz disp10
         mov dx,1900h
         xor bh,bh
         mov ah,2
         int 10h             ;隐蔽光标
         ret
disp1    endp
         even
disp2    proc near           ;封面信息显示子程序
         mov dx,es:[bx]      ;取行号列号
         inc bx
         inc bx
         mov cl,es:[bx]      ;取信息字符长度
         inc bx
         mov ch,es:[bx]      ;取显示属性
         inc bx
         mov bp,bx           ;置字符地址
         mov bl,ch           ;置属性
         xor ch,ch
         xor bh,bh           ;置显示页
         mov ax,1300h
         int 10h
         ret
disp2    endp
;重复显示子程序
         even
disp3    proc near          ;定位显示模块
         push ax            ;ah=显示长度,al=显示字符
         mov cl,ah          ;dx=显示行列号
         xor ch,ch
         push cx
         mov ah,2
         xor bh,bh
         int 10h            ;置光标
         pop cx
         pop ax
         mov ah,9
         xor bh,bh          ;显示页面
         mov bl,es:winc     ;取显示属性
         int 10h
         ret
disp3    endp
;保存窗口的内容,显示指定的信息,定时或按键后恢复窗口内容
         even
win      proc near          ;对话窗口子程序
         mov es:winc,al     ;保存显示属性
         xor al,al
         mov es:wint,al     ;分行显示清零
         mov es:winm,al
;计算窗口左右列号(上下行号固定为0bh-10h)
         mov al,[bx]        ;取信息长度 
         inc bx
         push bx            ;保存信息地址
         cmp al,49h         ;信息长度大于73则分两行显示
         jb win0
         sub al,40h         ;减去基本长度
         mov es:wint,al     ;保存剩余长度
         mov al,40h
win0:    add al,5           ;加空白边
         mov es:winw,al     ;保存宽度
         mov bl,al
         sar al,1           ;右移一位(除以2)
         mov ah,al
         mov al,27h
         sub al,ah          ;计算左列号
         mov es:winl,al     ;保存左列号
         add al,bl
         dec al
         mov es:winr,al     ;保存右列号
;保存窗口内容
         mov dh,0bh         ;对话框从11行开始
         mov ch,6           ;固定6行高
         mov bx,3000h       ;取缓存地址
win1:    mov dl,es:winl     ;取左列号
         mov cl,es:winw     ;取宽度
win2:    push dx            ;开始保存窗口字符及属性
         push cx
         push bx
         xor bh,bh          ;置页号
         mov ah,2
         int 10h            ;置光标位置
         mov ah,8
         xor bh,bh
         int 10h            ;读光标位置字符及属性
         pop bx
         mov [bx],ax        ;保存字符及属性
         inc bx
         inc bx
         pop cx
         pop dx
         inc dl             ;列号加1
         dec cl
         jnz win2           ;本行未完,继续
         inc dh             ;行号加1
         dec ch
         jnz win1           ;未完,继续下一行
;窗口内容保存完毕,清窗口
         xor bh,bh          ;页面
         mov bh,es:winc     ;取属性
         mov cl,es:winl     ;取左列号
         mov dl,es:winr     ;取右列号
         mov ch,0bh         ;开始行号
         mov dh,10h         ;结束行号
         mov ax,600h
         int 10h            ;清窗口
;画窗口框线
         mov ax,1c9h        ;c9=左上角表格线, 长度1
         mov dl,es:winl     ;左上角行列
         mov dh,0bh
         call disp3         ;调定位显示子程序
         mov dl,es:winl
         inc dl
         mov dh,0bh
         mov ah,es:winw
         dec ah
         dec ah             ;长度
         mov al,0cdh        ;cd=上边表格线
         call disp3
         mov dh,0bh
         mov dl,es:winr
         mov ax,1bbh        ;bb=右上角表格线,长度1
         call disp3
         mov dl,es:winl
         mov dh,10h
         mov ax,1c8h        ;c8=左下角表格线,长度1
         call disp3
         mov ah,es:winw
         dec ah
         dec ah             ;宽度
         mov al,0cdh        ;cd=下边表格线
         mov dl,es:winl
         inc dl
         mov dh,10h
         call disp3
         mov dl,es:winr
         mov dh,10h
         mov ax,1bch        ;bc=右下角表格,长度1
         call disp3
         mov dh,0ch         ;显示两边竖线,从0ch行开始
         mov cl,4           ;共4行
win3:    push cx
         push dx
         mov dl,es:winl     ;左边列号
         mov ax,1bah        ;ba=表格竖线,长度1
         push dx
         push ax
         call disp3
         pop ax
         pop dx
         mov dl,es:winr     ;右边列号
         call disp3
         pop dx
         inc dh             ;行号加一
         pop cx
         dec cl             ;次数减一
         jnz win3           ;未完继续显示
;显示窗口信息
         pop bx
         push bx
         mov bp,bx          ;置显示信息地址
         xor bh,bh          ;页面
         mov bl,es:winc     ;取显示属性
         mov al,es:winw
         sub al,6
         mov cl,al          ;显示信息长度
         xor ch,ch
         mov al,es:winl
         add al,3
         mov dl,al          ;显示信息的列号
         mov dh,0dh         ;显示信息的行号
         mov ax,1300h
         push dx
         int 10h            ;显示第一行信息
         pop dx
         pop bx
         cmp es:wint,0
         jz win4
         inc dh
         mov ax,40h
         add ax,bx
         mov bp,ax
         mov dl,es:wint     ;第二行信息的长度
         mov cl,dl
         sar dl,1
         mov al,27h
         sub al,dl
         mov dl,al
         xor ch,ch
         mov bl,es:winc
         xor bh,bh
         mov ax,1300h
         int 10h            ;显示第二行信息
win4:    mov dx,1900h
         xor bh,bh
         mov ah,2
         int 10h             ;隐蔽光标
;等待按键
         xor ah,ah
         mov winm,al        ;清标志
         int 16h            ;读键盘
         and al,3fh         ;屏蔽高二位(大写转换为小写)
         cmp al,39h         ;'Y'确认键
         jnz win5
         mov al,1
;恢复窗口内容
win5:    mov dh,0bh         ;对话框从11行开始
         mov ch,6           ;固定6行高
         mov bx,3000h       ;取缓存地址
win6:    mov dl,es:winl     ;取左列号
         mov cl,es:winw     ;取宽度
win7:    push dx            ;开始恢复窗口原字符及属性
         push cx
         push bx
         mov ah,2
         xor bh,bh          ;置页号
         int 10h            ;置光标位置
         pop bx
         mov ax,es:[bx]     ;取字符及属性
         push bx
         mov bl,ah          ;置属性
         mov ah,9
         xor bh,bh
         mov cx,1
         int 10h            ;写光标位置字符及属性
         pop bx
         inc bx
         inc bx
         pop cx
         pop dx
         inc dl             ;列号加1
         dec cl
         jnz win7           ;本行未完,继续
         inc dh             ;行号加1
         dec ch
         jnz win6           ;未完,继续下一行
         cmp es:winm,0
         jz win8
         clc                ;清c标志
         jmp win9
win8:    stc
win9:    ret
win      endp
         even
winw     db 0               ;对话框宽度
winl     db 0               ;对话框左列号
winr     db 0               ;对话框右列号
winc     db 1eh             ;对话框属性
winm     db 0               ;>0,对话框确认标志
wint     db 0               ;>0,第二行显示的信息长度
         even
int1c    proc near          ;定时器中断(计时)模块
         inc es:cal1        ;计数
         ret
         even
int1c0   dw 0               ;保存原时钟中断代码
int1c1   dw 0
int1c    endp
;软盘测试子程序,返回:置C,无磁盘;清C,有磁盘 al=0可写,al=1写保护
         even
chkfd    proc near
chk001:  mov cl,4           ;软盘测试,四次
chk002:  push cx
         mov ax,201h        ;读一个扇区
         mov bx,2c00h       ;数据缓冲区设在2c00H处
         mov cx,1           ;从0道1扇区开始读
         xor dx,dx          ;读0驱动器(A盘)0面(头)
         int 13h
         pop cx
         jnc chk004         ;读成功,跳转
         dec cl
         jnz chk002         ;继续测试
chk003:  stc
         ret                ;测试失败,返回
chk004:  mov cl,4
chk005:  push cx
         mov ax,301h        ;写一个扇区
         mov bx,2c00h       ;数据缓冲区设在2c00H处
         mov cx,1           ;从0道1扇区开始读
         xor dx,dx          ;读0驱动器(A盘)0面(头)
         int 13h
         pop cx
         jnc chk006         ;写成功,跳转
         dec cl
         jnz chk005         ;继续测试
         mov al,1           ;置写失败标志
         jmp chk007
         even
chk006:  xor al,al          ;置可写标志
chk007:  clc
         ret                ;测试成功,返回
chkfd    endp
;保存原硬盘引导扇区内容子程序
         even
save     proc near
sa0:     call chkfd          ;调软盘测试模块
         jnc sa2             ;有软盘,跳转
         mov bx,offset messd ;无软盘提示
         mov al,47h
         call win
         jc sa0              ;继续测试
sa1:     stc                 ;置失败标志
         ret                 ;返回
sa2:     cmp al,0            ;测试是否可写
         jz sa3              ;可写入,跳转
         mov bx,offset messc ;写入失败提示
         mov al,47h
         call win
         jc sa0              ;继续测试
         jmp sa1             ;放弃测试
         even
sa3:     mov cl,4            ;操作四次
sa4:     push cx
         mov bx,2c00h
         mov ax,201h
         mov cx,1
         mov dx,80h          ;读硬盘引导扇区
         int 13h
         pop cx
         jnc sa5             ;读成功,跳转
         dec cl
         jnz sa4             ;继续读
         jmp sa1             ;放弃操作
         even
sa5:     mov cl,4            ;操作四次
sa6:     push cx
         mov ax,301h
         mov bx,2c00h
         mov cx,101h
         mov dx,100h         ;写入软盘1磁头1磁道1扇区
         int 13h
         pop cx
         jnc sa7             ;写成功,跳转
         dec cl
         jnz sa6             ;继续写
         jmp sa1             ;放弃操作
         even
sa7:     clc                 ;清c标志
         ret
save     endp
;恢复原硬盘引导扇区内容子程
         even
resa     proc near
         mov bx,offset messg ;提示插入软盘
         mov al,3fh
         call win
res0:    call chkfd          ;测试软盘
         jnc res2            ;有软盘,跳转
         mov bx,offset messd ;无软盘提示
         mov al,4fh
         call win
         jc res0             ;继续测试
res1:    stc                 ;置失败标志
         ret                 ;返回
res2:    mov bx,2c00h
         mov ax,201h
         mov cx,101h
         mov dx,100h         ;读入软盘1磁头1磁道1扇区
         int 13h
         jnc res3            ;读成功,跳转
         mov bx,offset messd ;提示未准备好
         mov al,4fh
         call win
         jc res2             ;重读
         jmp res1            ;放弃
         even
res3:    mov bx,2c00h
         cmp word ptr[bx+1feh],0aa55h  ;判断结束标志55h
         jz res4             ;有正确结束标志,跳转
         mov bx,offset messa ;没有发现备份系统提示
         mov al,4fh
         call win
         jmp res1            ;失败返回
         even
res4:    mov cl,4            ;写四次
res5:    push cx
         mov ax,301h
         mov cx,1
         mov dx,80h          ;写硬盘引导扇区
         int 13h
         pop cx
         jnc res6            ;写成功,跳转
         dec cl
         jnz res5            ;继续写
         mov bx,offset messf ;写失败提示
         mov al,4fh
         call win
         jmp res1            ;放弃操作
         even
res6:    mov bx,offset messb ;恢复完成提示
         mov al,3fh
         call win
         clc                 ;清c标志
         ret
resa     endp
;安装ZERO系统子程序(先保存原系统,后安装ZERO)
         even
setup0   proc near
         mov al,ds:[7db0h]
         cmp al,1            ;测ZERO系统安装标志
         jnz se02            ;没有安装过ZERO 
         mov bx,offset mess9 ;已经安装过,是否重装
         mov al,47h
         call win
         jc se03             ;跳转重装
se01:    stc
         ret                 ;不重装,返回
se02:    call save           ;保存原系统
         jnc se03            ;保存成功,跳转
         jmp se01            ;保存失败,返回
         even
se03:    call setup1         ;调安装模块
         ret
setup0   endp
;恢复ZERO系统子程序(不保存原系统,安装ZERO)
         even
setup1   proc near           ;先安装ZERO系统到硬盘0道0柱第3扇区
         mov cl,4            ;操作四次
se11:    push cx
         mov bx,4000h        ;磁盘数据缓冲区
         mov ax,20ah         ;读10个扇区
         mov cx,101h
         xor dx,dx           ;读入软盘0磁头1磁道1-10扇区
         int 13h
         pop cx
         jnc se13            ;读成功,跳转
         dec cl
         jnz se11            ;重读
se12:    stc                 ;操作失败,返回
         ret
se13:    mov cl,4            ;写四次
se14:    push cx
         mov bx,4000h
         mov ax,30ah         ;写10个扇区
         mov cx,3            ;写入硬盘0磁头0磁道3扇区开始的扇区
         mov dx,80h
         int 13h
         pop cx
         jc se15             ;写失败,返回
         dec cl
         jnz se14            ;重试
         jmp se12            ;放弃,返回
         even
se15:    mov bx,offset hdbt0 ;再安装硬盘引导程序
         mov si,bx           ;源地址
         mov di,7c00h        ;目的地址
         mov cx,0b0h         ;长度
         cld                 ;置传输方向
         movsw               ;安置好引导程序
         mov al,1
         mov ds:[7db0h],al   ;置ZERO安装标志
         mov ax,301h
         mov bx,7c00h
         mov cx,1
         mov dx,80h          ;写硬盘0磁头0柱面1扇区
         int 13h
         jc se16             ;安装失败,跳转
         clc                 ;清c标志
         ret                 ;安装成功,返回
         even
se16:    mov bx,offset messe ;安装失败提示
         mov al,4fh
         call win
         stc
         ret
setup1   endp
         even
hdbt0    db 0fah,33h,0c0h,8eh,0d0h,0bch,0,7ch  ;硬盘引导程序
         db 8bh,0f4h,50h,7,50h,1fh,0fbh,0fch
         db 0beh,50h,7ch,0e8h,34h,7ch,0b8h,0ah ;10
         db 3,0bbh,0,6,0b9h,3,0,0bah
         db 80h,0,0cdh,13h,72h,5h,0eah,0       ;20
         db 6,0,0,0beh,68h,7ch,0e8h,34h
         db 7ch,0ebh,0feh,0,0ach,3ch,0,74h     ;30
         db 0bh,56h,0bbh,7,0,0b4h,0eh,0cdh
         db 10h,5eh,0ebh,0f0h,0cbh,0,0,0       ;40
         db 0,0,0,0,0,0,0,0
         db 53h,74h,72h,61h,74h,69h,6eh,67h    ;50
         db 20h,5ah,45h,52h,4fh,20h,56h,20h
         db 30h,2eh,31h,30h,2eh,2eh,2eh,0      ;60
         db 54h,68h,65h,20h,5ah,45h,52h,4fh
         db 20h,73h,79h,73h,74h,65h,6dh,20h    ;70
         db 66h,61h,69h,6ch,75h,72h,65h,2ch
         db 79h,9fh,75h,20h,6dh,75h,73h,74h    ;80
         db 20h,72h,65h,70h,6ch,65h,20h,5ah
         db 45h,52h,4fh,20h,73h,79h,73h,74h    ;90
         db 65h,6dh,20h,66h,72h,6fh,6dh,20h
         db 66h,6ch,6fh,70h,70h,79h,20h,61h    ;a0
         db 67h,61h,69h,6eh,2eh,0,0,0          ;长度为b0h
hdbt     proc near           ;硬盘引导程序(伪代码)    
         cli                 ;关中断         FA
         xor ax,ax           ;清AX寄存器     33C0
         mov ss,ax           ;堆栈寄存器清零 8ED0
         mov sp,7c00h        ;置堆栈段指针   BC007C.
         Mov si,sp           ;               8BF4
         push ax             ;置扩展段指针   50
         pop es              ;               07
         push ax             ;置数据段指针   50
         pop ds              ;               1F
         sti                 ;开中断         FB
         cld                 ;正向传输       FC.
         Mov si,7c80h        ;信息地址       BE507C
         call dispb          ;显示Strating ZERO V0.10. E8347C
         mov ax,30ah         ;读10个扇区               B80A.03
         mov bx,600h         ;存放在600H开始的地址     BB0006
         mov cx,3            ;从0头0道3扇区开始读      B90300
         mov dx,80h          ;读主硬盘       BA.8000
         int 13h             ;               CD13
         jc hdb1             ;               7205
         jmp 0:600           ;               EA00.060000
         even
hdb1:    mov si,7ca0h        ;显示失败信息   BE687C
         call dispb          ;               E834.7C
hdb2:    jmp hdb2            ;               EBFE
hdbt     endp
         even

dispb    proc near
db0:     lodsb               ;读一个字符     AC
         cmp al,0            ;               3C00
         jz hdb2             ;字符结束,跳转  74.0B
         push si             ;               56
         mov bx,7            ;黑底白字       BB0700
         mov ah,0eh          ;显示           B40E
         int 10h             ;               CD.10
         pop si              ;               5E
         jmp db0             ;               EBF0
         ret                 ;               CB
dispb    endp
         even
stra0    db 'Strating ZERO V0.12…'
stra1    db 'The ZERO system failure,'
         db 'you must reple ZERO system from floppy again.'

         even
;操作系统ID转换表
idcode   db 0,14h,19h,0,15h,1,16h,0,0,0,0,17h,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,1bh,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
menu     db "Can't know Sys  "
         db "DOS Expand Parti"  ;05
         db "2               "
         db "3               "
         db "4               "
         db "5               "  ;
         db "6               "
         db "7               "  ;
         db "8               "
         db "9               "  ;
         db "A               "
         db "B               "  ;
         db "C               "  ;
         db "D               "
         db "E               "  ;
         db "F               "
         db "10              "
         db "Setup ZERO 0.12 "  ;固定为11H开始
         db "Reple old system"
         db "Reple ZERO 0.12 "
         db "DOS (12 bit FAT)"  ;01
         db "DOS (16 bit FAT)"  ;04
         db "DOS or WIN 9.X  "  ;06
         db "DOS (32 bit FAT)"  ;0b
         db "Windows NT 4.X  "
         db "XENIX  root     "  ;02
         db "Xteam Linux 1.0 "
         db "NOVELL          "  ;64
         even
sele0    db 0                ;当前的活动分区
sele1    db 0                ;第一分区ID号     
sele2    db 0                ;第二分区ID号
sele3    db 0                ;第三分区ID号
sele4    db 0                ;第四分区ID号
sele5    db 0
sele6    db 0
sele7    db 0
sele8    db 0
sele9    db 0
selea    db 0
seleb    db 0
selec    db 0               
chk      db 1               ;键按下标志
cal0     db 9               ;总*计数
cal1     db 0               ;秒计数
disx     dw 1722h           ;23行34列开始显示*号
men0     db 0               ;总菜单条数
men1     db 0               ;当前菜单条号
;(空格)ZERO显示数据
zero1    db 10,2,5,17,2,5,24,2,4
         db 32,2,3,14,3,1,17,3,1
         db 24,3,1,28,3,1,31,3,1
         db 35,3,1,13,4,1,17,4,1
         db 24,4,1,28,4,1,31,4,1
         db 35,4,1,12,5,1,17,5,4
         db 24,5,4,31,5,1,35,5,1
         db 11,6,1,17,6,1,24,6,1
         db 26,6,1,31,6,1,35,6,1
         db 10,7,1,17,7,1,24,7,1
         db 27,7,1,31,7,1,35,7,1
         db 10,8,5,17,8,5,24,8,1
         db 28,8,1,32,8,3
         even
zero2    db 2eh,5,6,1bh,"V 0.12"              ;界面显示
         even
zero3    db 2eh,6,15h,1bh,"Copyright by Hujiajun"
         even
zero4    db 2eh,7,23,1bh,"http://softroom.163.net"
         even
zero5    db 2eh,8,23,1bh,"E-mail:softroom@163.net"
         even
zero6    db 20h,15h,10h,1eh,"Welcome to ZERO!"
         even
zero7    db 47h,18h,7,17h,"2000.05"
;对话框、警告框提示信息(因本人的英语太差,下面的错误请协助更正)
         even
mess1    db 32h,'Do you wish to setup ZERO into your
          computer?(y/n)'
         ;你确实要将ZERO V0.10安装到你的计算机上吗?
         Even
mess2    db 37h,'Do you wish to reple ZERO system from 
            floppy disk?(y/n)'
         ;你确实要从软盘上恢复ZERO系统吗?
         Even
mess3    db 3ah,'Do you wish to reple the old system from
            floppy disk?(y/n)'
         ;你确实要从软盘上恢复原有的系统吗?
         Even
mess4    db 1dh,'Do you wish to continue?(y/n)'
         ;你想继续吗?
         Even
mess5    db 1ch,'Press any key to continue…'
         ;按任意键继续…
         even
mess6    db 7bh,'  Setup of ZERO now is completed.  The
           computer will be reset,  '
         db 'take out floppy from drive A,and press any key
             to continue.'
         ;ZERO 的安装已经完成,计算机将要重新启动,
         ;请把软盘从驱动器A中取出,并按任意键继续。
         Even
mess7    db 7bh,'Reple ZERO system now is completed. The
            computer will be reset, '
         db 'take out floppy from drive A,and press any key 
          to continue.'
         ;恢复ZERO系统已经完成,计算机将要重新启动,
         ;请把软盘从驱动器A中取出,并按任意键继续。
         Even
mess8    db 46h,'The partition of selected is not any system,
           press any key to continue.'
         ;选中的分区没有任何操作系统,按任意键继续。
         Even
mess9    db 3dh,'The ZERO was exist,do you reple ZERO system
            from floppy?(y/n)'
         ;ZERO 已经存在,你要从软盘上恢复ZERO系统吗?
         Even
messa    db 2bh,'Not fond old system in floppy,cannot reple.'
         ;在软盘中没有发现备份的原系统,不能够进行恢复
         even
messb    db 1fh,'The old system now is repleted.'
         ;原有的系统已经恢复完成.
         Even
messc    db 44h,'Because well write old system,pless open the
            write protect of flppy.'
         ;请打开写保护,以便将原系统保存在软盘上.
         Even
messd    db 2dh,'The device A not ready,are you continue?(y/n)'
         ;软盘A没有准备好,继续吗?
         Even
messe    db 2ch,'Setup failure,press any key to contine?(y/n)'
         ;安装失败,你要继续吗?
Messf    db 2ch,'Reple failure,press any key to contine?(y/n)'
         ;恢复失败,你要继续吗?
Messg    db 26h,'Please inseter ZERO floppy in drive A.'
         ;请插入ZERO 软盘到驱动器A
messh    db 3ah,'Write protect error writing drive A,are you
            continue?(y/n)'
         ;A盘写出错,你要继续吗?
Messi    db 5ah,'The copies of old system DATA in your floppy
           will be lost,          '
         db 'are you continue?(y/n)'
         ;软盘中原系统数据将会丢失,你要继续吗?
Code     ends
         end begin

注:

发表日期:2005-1-13     修改日期:

备案序号:赣ICP备05002359号

建议使用1024*768分辩率浏览 ☆版权所有 摘抄或转载须得到书面许可☆ Hujiajun ©1999,2016
E-Mail: hu-jj@21cn.com