可以用前一篇操作系统内核加载器(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
原文地址:http://blog.csdn.net/yuzhihui_no1/article/details/41869291