可以用前一篇操作系统内核加载器(x86汇编)的加载器来加载这个RTC中断程序,就可以显示时间了。
;user.asm
;程序的头文件,整个程序的信息表
;--------header-----------------------------------
section header align=16 vstart=0
program_length dd program_end
program_entry dw start
dd section.code.start
section_count dw (section_end-section_begin)/4
section_begin:
section_code dd section.code.start
section_data dd section.data.start
section_stack dd section.stack.start
section_int dd section.interupt.start
section_end:
;header end
;另外申请一个段用来作中断处理
;--------------interupt-------------------------
section interupt align=16 vstart=0
RTC_INT:
push ax
push bx
push cx
push dx
push es
push ds
;等待读取RTC的时间
.waits:
mov dx , 0x70
mov al , 0xa
or al , 0x80 ;阻断NMI
out dx , al
mov dx , 0x71
in al , dx
test al , 0x80
jnz .waits
mov cx , 3
xor al , al
;读取RTC秒 ;读取RTC分 ;读取RTC时
read_time:
or al , 0x80
out 0x70 , al
mov bl , al
in al , 0x71
push ax
mov al , bl
add al , 2
loop read_time
;读取寄存器C,让再次产生中断
mov dx , 0x70
mov al , 0xc ;这次不阻止NMI中断
out dx , al
mov dx , 0x71
in al , dx
;开始准备显示时间
mov ax , 0xb800
mov es , ax
mov bx , 12*160 + 40*2
mov cx , 3
show_rtc:
pop ax
call bcd_to_ascii
mov [es:bx] , ah
mov [es:bx+2] , al
cmp bx , (12*160 + 40*2 + 12)
je @1
mov al ,':'
mov [es:bx+4] , al
not byte[es:bx+5]
@1:
add bx , 6
loop show_rtc
mov al , 0x20
out 0x20 , al
out 0xa0 , al
pop ds
pop es
pop dx
pop cx
pop bx
pop ax
iret
;bcd码转ascii码 ==》四个bcd转换成一个十进制数(0~9),十进制数加上0x30成十六进制数
bcd_to_ascii:
mov ah , al
and al , 0x0f
add al , 0x30
shr ah , 4
and ah , 0x0f
add ah , 0x30
ret
;bcd_to_ascii end
;interupt end
;-------------code begin-------------------------
section code align=16 vstart=0
;设置堆栈
start:
mov ax , [section_stack]
mov ss , ax
mov sp , ax
;设置数据段
mov ax , [section_data]
mov ds , ax
;显示安装中断前的内容
mov bx , begin_msg
call print_string
mov bx , install_msg
call print_string
cli
;安装中断
push ds
mov ax , 0x00
mov ds , ax
mov al , 0x70 ;从片默认开始中断号,主片为:0x80
mov bl , 4
mul bl
mov bx , ax
mov word[ds:bx] , RTC_INT
mov ax , [es:section_int]
mov word[ds:bx+2] , ax
pop ds
;设置寄存器B ;coms端口 0x70 / 0x71
mov dx , 0x70
mov al , 0xb
or al , 0x80 ;禁止NMI中断
out dx , al
mov dx , 0x71
mov al , 0x12
out dx , al
;读取寄存器C 开始中断
mov dx , 0x70
mov al , 0xc
out dx , al
mov dx , 0x71
in al , dx
;设置从片的未决字位,0xa1 ;主片为 0x21
mov dx , 0xa1
in al , dx
and al , 0xfe
out dx , al
sti
mov bx , done_msg
call print_string
;显示time
mov ax , 0xb800
mov es , ax
mov si , time_msg
mov di , 12*160 + 32*2
mov cx , (data_end - time_msg)
show_time:
mov al , [si]
mov [es:di] , al
inc si
add di , 2
loop show_time
.halt:
hlt
jmp .halt
;打印字符串的过程
;--------------------print_string---------------
print_string:
mov cl , [bx]
cmp cl , 0
jz .ret
call print_char
inc bx
jmp print_string
.ret:
ret
;print_string end
;---------------------print_char-----------------
print_char:
push ax
push bx
push cx
push dx
push ds
push es
;首先获取光标的位置
mov dx , 0x3d4
mov al , 0xe
out dx , al
mov dx , 0x3d5
in al , dx
mov ah , al
mov dx , 0x3d4
mov al , 0xf
out dx , al
mov dx , 0x3d5
in al , dx
mov bx , ax
;判断是不是回车符
cmp cl , 0xd
jnz if_nextLine
mov bl , 80
div bl
mul bl
mov bx , ax
jmp set_cursor ;其实这个还没有清屏,只是光标回车,但这一行还是有数据
; jmp roll_screen
;判断是否为换行符
if_nextLine:
cmp cl , 0xa
jnz is_char
add bx , 80
jmp roll_screen
;确定为正常字符
is_char:
mov ax , 0xb800
mov ds , ax
shl bx , 1
mov [bx], cl
shr bx , 1
inc bx
roll_screen:
cmp bx , 2000 ;25 x 80 =2000
jl set_cursor
mov es , ax
cld
mov si , 0xa0 ;16 x 10 = 80 x 2
mov di , 0x0
mov cx , 1920
rep movsw
mov bx , 1920
clean_lastLine:
mov cx , 80
clean_Line:
mov word[di] , 0x720
add di , 2
loop clean_Line
set_cursor:
mov dx , 0x3d4
mov al , 0xe
out dx , al
mov dx , 0x3d5
mov al , bh
out dx , al
mov dx , 0x3d4
mov al , 0xf
out dx , al
mov dx , 0x3d5
mov al , bl
out dx , al
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
ret
;print_stringf end
;code end
;-------------data begin-------------------------
section data align=16 vstart=0
begin_msg db 'begin ...', 0xd, 0xa, 0
install_msg db 'installing...', 0xd,0xa, 0
done_msg db 'done....',0
time_msg db 'time:'
data_end:
;data end
;-------------stack begin-------------------------
section stack align=16 vstart=0
resb 256
stack_end:
;stack end
;-------------tail begin--------------------------
section tail align=16
program_end:
;tail end
转载地址:
http://blog.csdn.net/yuzhihui_no1/article/details/41869291