当前位置:首页 > 我的程序 > 正文内容

谈谈计算机的RTC电路和IO编程的汇编指令。

Peirre3年前 (2021-09-15)我的程序587

这两天在github.com上写代码,出了几个例子。

其中有两个汇编语言编的是时钟代码。

这两个例子可以显示系统时钟内存的数据内容。

一个是利用BIOS的中断,一个是利用DOS中断。

这两个汇编程序主要是利用汇编语言的两个指令对I/O口通讯。

一个是 in al,71,一个是 out 70,al

70,和 71端口是系统的时钟IO通讯口。还有72和73也有同样效果。

在虚拟机上测试了,还有,通过低级的端口控制,发现我的电脑主板X79

72,73这个端口是无效果的。

实际显示可以从00h-FF显示完全从80以后是重复00-7F的数据的。

如果资料是正确的话,说明这些可能有些端口只能设置一次。还是BIOS设置的。

一个是直接显示芯片RAM。一个是映射RAM。

这个RTC时钟端口,也保存了系统其它未公开信息,只作简单说明。

;我对CMOS时钟数端口的理解
;时钟设置端口在实模式下是端口70/71,72/73
;CMOS的时钟有两种模式DV0=0模式,DV0=1模式
;端口70模式是只读模式,端口71模式是只写模式
;0e-3f 是RAM 50字节用户空间
;40-7f 是RAM 64字节用户空间
;80-ff 是128字节RAM扩展用户空间
;*00-ff 是256字节RAM用户空间*
;DV0=1模式下 50 = +offset 80(DV0=0下的80)
;----------------------------------------------
;DV0=1模式可用地址
;00 秒
;01 秒警
;02 分
;03 分警
;04 时
;05 时警
;06 星期数据
;07 月数据
;08 月
;09 年
;0a 寄存器 A
;0b 寄存器 B
;0c 寄存器 C
;0d 寄存器 D
;32 是辅助国家时区(DV0=0)
;48 是国家时区代码(DV0=1)
;50 是扩展内存端口地址
;53 是护展内存端口数据
;7e 计数复位
;注:秒警,分警,时警相当于闹钟的意思
;---------------------------------------------
;地址00 数值为00-59 当 0b 寄存器 B = 1 时 设置
;地址00 数值自动被硬件更新,软设置停止
;地址01 高位为C(字节[7:6]=11b)使用
;地址01 位设置为1不使用
; 02-03,04-05 性质同上
; 04区别数值为00-23
; 06数值01-07 星期日值为1
; 07数值01-28 软件设置后自动停止
; 08数值01-12 同上
; 09数值00-99 同上
;++++++++++++++++++++++++++++++++++++++++++++
;寄存器 A 字节[3:2:1:0]
;              0 0 0 0   默认最快设置
;              0 0 0 1   256Hz(3.90625微秒)
;              0 0 1 0   128Hz(7.8125
;              0 0 1 1   8.192kHz(122.070毫秒
;              0 1 0 0   4.096kHz(244.141毫秒
;              0 1 0 1   2.048kHz(488.281毫秒
;              0 1 1 0   1.024kHz(976.5625毫秒
;              0 1 1 1   512Hz(1.953125微秒
;              1 0 0 0   256Hz(3.90625微秒
;              1 0 0 1   128Hz(7.8125微秒
;              1 0 1 0   64Hz(15.625微秒
;              1 0 1 1   32Hz(31.25微秒
;              1 1 0 0   16Hz(62.5微秒
;              1 1 0 1   8Hz(125微秒
;              1 1 1 0   4Hz(250微秒
;              1 1 1 1   2Hz(500微秒
;寄存器 A 字节[:4]DV0 = 0 或 1 端口72/73访问256字节RAM内存
;地址7f 字节[:0]为1可以访问RTC内存

还有英文资料,这资料是几十年前的。现在的只是补充。

00  RTC seconds
01  RTC seconds alarm
02  RTC minutes
03  RTC minutes alarm
04  RTC hours
05  RTC hours alarm
06  RTC day of week
07  RTC day of month
08  RTC month
09  RTC year
0A  RTC Status register 
A:

    RTC Status Register A
    bit0-3: rate selection Bits for divider output
            frequency (set to 0110 = 1.024kHz, 976.562鎠)
    bit4-6: 22 stage divider, time base being used;
            (initialized to 010 = 32.768kHz)
    bit7:   1=time update in progress, 0=time/date available

0B  RTC Status register 
B:

    RTC Status Register B
    bit0:   1=enable daylight savings, 0=disable (default)
    bit1:   1=24 hour mode, 0=12 hour mode (24 default)
    bit2:   1=time/date in binary, 0=BCD (BCD default)
    bit3:   1=enable square wave frequency, 0=disable
    bit4:   1=enable update ended interrupt, 0=disable
    bit5:   1=enable alarm interrupt, 0=disable
    bit6:   1=enable periodic interrupt, 0=disable
    bit7:   1=disable clock update, 0=update count normally

0C  RTC Status register C (read only):

    RTC Status Register C  (read only)
    bit0-3: reserved (set to 0)
    bit4:   update ended interrupt enabled
    bit5:   alarm interrupt enabled
    bit6:   periodic interrupt enabled
    bit7:   IRQF flag

0D  RTC Status register D (read only):

   RTC Status Register D  (read only)
   bit0-6:  reserved (set to 0)
   bit7:    1=CMOS RAM has power, 0=CMOS RAM has lost power

0E  Diagnostic status byte:

   Diagnostic Status Byte
    bit0-1: reserved
    bit2:   1=time is invalid, 0=ok (POST validity check)
    bit3:   1=fixed disk 0 failed initialization, 0=ok
    bit4:   1=memory size doesn't match config info, 0=ok
    bit5:   1=invalid config info found, 0=ok (see below)
    bit6:   1=config record checksum is bad, 0=ok
    bit7:   1=RTC lost power, 0=power state stable

0F  Shutdown status byte:

      0  soft reset or unexpected shutdown
      1  shut down after memory size determination
      2  shut down after memory test
      3  shut down with memory error
      4  shut down with boot loader request
      5  JMP DWORD request with INT init
      6  protected mode test 7 passed
      7  protected mode test 7 failed
      8  protected mode test1 failed
      9  block move shutdown request
      A  JMP DWORD request without INT init

10  Diskette drive type for A: and B:

   Diskette drive type for A: and B:
   bit0-3:  second diskette type
   bit4-7:  first diskette type

       0000  no drive installed
       0001  DSDD 48 TPI drive
       0010  DSQD 96 TPI drive
       other values are reserved

11  Reserved
12  Fixed disk drive type for drive 0 and drive 1

    Diskette drive type for A: and B:
    bit0-3:  second hard disk drive code (0000=no disk)
    bit4-7:  first hard disk drive code (0000=no disk)

13  Reserved
14  Equipment byte

    Equipment byte
    bit0:    1=diskette drives installed, 0=none
    bit1:    1=math coprocessor installed, 0=none
    bit2-3:  unused
    bit4-5:  primary display
    bit6-7:  number of diskette drives installed

    Bits                       Bits
     54  Primary Display        76  Number of Drives
     00  reserved               00  1 diskette drive
     01  40 column color        01  2 diskette drives
     10  80 column color        10  reserved
     11  monochrome             
11  reserved

15  LSB of system base memory in 1k blocks
16  MSB of system base memory in 1k blocks
17  LSB of total extended memory in 1k blocks
18  MSB of total extended memory in 1k blocks
19  Drive C extension byte (reserved AT)
1A  Drive D extension byte (reserved AT)
1B  13 bytes reserved
2E  CMOS checksum of bytes 10h-20h (MSB)
2F  CMOS checksum of bytes 10h-20h (LSB)
30  LSB of extended memory size found above 1 megabyte during POST
31  MSB of extended memory size found above 1 megabyte during POST
32  Date century byte in BCD ( BIOS interface to read and set)
33  Information flags (set during power-on)

    Information Flags
    bit0-5:  reserved
    bit6:    initial setup message flag
    bit7:    1=IBM 128k expansion installed, 0=none

34  12 bytes reserved

Programming Considerations:

Write CMOS address to read or write to port 70h
Read/write port 71h to get/set data


- the 
information here is only applicable to AT and PS/2 systems
- INT 1A is used 
to read/set the Time of Day and Alarm.  To use the
   alarm, INT 4A must be a valid interrupt service routine.
- configuration settings are maintained 
using the Motorola MC146818
   Real Time Clock.  Each of this chips 64 memory registers is used
   for storage (0-3F).
- Bit 5 of the diagnostic (0Eh) 
status byte is set during a power
   on test.  This Bit is set if no floppy disks are found or the
   display doesn't match the system display switch setting.
- all addresses sent to port 70h have Bits 7&6 clear since Bit 7
   of port 70h is used to enable/disable NMI.  Setting this Bit 7
   enables NMI, clearing this Bit disables NMI.
- when masking the NMI through 
using port 70H, port 71H should be
   read immediately after or the RTC may be left in an unknown state.
   This wont affect the PS/2 watchdog timer or system channel timeout.

这是英文说明,可以对照我的注释看,英文不作翻译,只是让大家了解。

1.jpg

这是CMOS的RAM内存区,实际扩展后可以显读256字节。事实上,各个型号和芯片组的电路组合是不相同,但是总体一样的。

上表是常用数据已经公布了二十多年,为什么没相关的研究资料和项目,因为486 DX 440之后扩展了数据。

在486DX之前一直关注这个数据,因为那时的BIOS是只读的,之后就可写BIOS了。而自己为了生活也在做其它事情。

这是公开的数据,不过资料不太好找,所以贴到这里了。网上还是找得到的。

我的项目:http://github.com/wafer333/bootinfo 项目

---------------------------------------------------------------------

1eLKx8Cp1blSVEMgUE28xLTmxvc1ZS81Zr/JtsHE2sjdoaM=

1eLA772ru+G808jrw9jD3M7EtbW12Na3o6zQ6NKqwfTR1KOswfTR1LK7uau/qqGjA==

---------------------------------------------------------------------

Base64解码

以上是数据结构。

X79的主板电路图

--------------------------------------------------------------------------------

1eLA78u1w/e1xMrHxMfXz8mr1LK149eiw/e1xLXnwre+zcrHUlRDtefCt6O

sxuTW0NPQzPW/ydLUzai5/bzTyMXQxbrFo6zWu734sruz9qGjy7XD983is

r/OtNaqyeixuL/J0tS4xNC0Q01PU7K/t9Y=

--------------------------------------------------------------------------------

Base64解码

这紫色小圆点指示的就是RTC电路

再说一下汇编的指令 in和out.

这个指令是传递IO口数据的,所以使用方法很简单。

但是要知道输入输出口的设备是各不相同的。

所以一个设备一个用法,有的设备本身有设备的BIOS不过计算机CPU看不到设备指令。

有的设备会挂一个中断程序,由设备BIOS自带,或者在计算机的BIOS中。

我说的设备BIOS又叫火线也叫firware,也叫固件。

如果直接用汇编控制IO设备,那就用in,out。不过还要知道设备的延迟,因为设备运转比CPU慢。

IO地址新计算机可以是0x-0xffff,这条电路总线是和内存总线不一样的,不直接访问。

IO地址在计算机中是特定和固定的。一个硬件一个地址,不可以变化。【这太重要】

简单说明一下,因为这不是一本书可以说清楚的。贴个IO地址表就明白了。

这是基本的8位常用IO地址表,当然,还有12位的和16位的地址表,设备很多,本网站有篇文章是USB设备地址,可以参考。

有的地址的数据是索引值,每个值控制着数据的数据。举个例子。

mov al,2eh

out 70h,al

然后

in al, 71h

2e值是索引值。

在一些端口中,两次

in al,71h

in al,71h 

值是不一样的,这个要注意。

如果外设反应到 al,的字节是 FFh

注意了,设备正忙,CPU要有耐心等待,或者做别的工作,由int 中断程序完成。

上面x79的每根IO线路的设备会在特殊的情况下使能。让CPU工作。【说得浓缩了点】

未尽资料,简介到这里了。。。。

贴上测试代码。boch 2.7下通过。

format binary as 'img'
org 7c00h
;测试代码开始
;读时间
start:
mov ax,cs
mov ds,ax
mov es,ax
mov al,56h
mov dx,0xcd6
out dx,al
mov dx,0xcd7
in ax,dx
and ax,111111111011111b
out dx,ax
mov al,57h;设置PM Reg 0x57[5]=1
mov dx,0cd6h
out dx,al
mov dx,0cd7h
in al,dx
and al,0100000b;AltCmosMapEn
out dx,al
mov al,24h;AcpiMMioEn
mov dx,0cd6h
out dx,al
mov dx,0cd7h
in ax,dx
and ax,11b;AcpiMMioDecodeEn=1  AcpiMMioSet=1 I/O-mapped 空间
out dx,ax;[31:13] FED8_00
mov al,0ah
out 70h,al
in al,71h
and al,110000b
out 71h,al
mov al,7fh
out 70h,al
mov al,1
out 71,al
mov cx,0ffh
mov al,0h
mov di,data1
mov si,data1
s0:
out 70h,al
push ax
in al,71h
stosb
    pop ax
    inc al
    dec cx
  jnz s0
mov ax,0
a1:
push ax
call printnum1
mov al,":"
int 10h 
mov al," "
int 10h
mov cx,16
call n15
pop ax
inc ax
cmp ax,16
jl a1
jmp $
nop 
mov si,data1
mov di,si
;===================
mov dx,15
n0:
push dx
mov cx,16
call n15
pop dx
dec dx
jnz n0
jmp $
n15:
call printnum
loop n15
mov ax,0e0dh
int 10h
mov ax,0e0ah
int 10h
ret
printnum:
lodsb
printnum1:
push ax
sar al,4
call dnum
mov ah,0eh
int 10h
pop ax
call dnum
mov ah,0eh
int 10h
mov ax,0e20h
int 10h
ret
dnum:
and al,0fh
cmp al,0ah
jl  d1
add al,7h
d1:
add al,30h
ret
screen:
mov si,data2
mov al,byte [si]
call write
jz write_done
jmp screen
write_done:
xorah,ah;暂停键功能
int16h;BIOS键盘中断
loop write_done
write:
movah,0eh;字符终端显示输出功能函数号
mov bx,0003h;显示属性 (weird...)
.more:
lodsb;读到al一个字节
oral,al
jz.done
int10h;BIOS显示中断
jmp.more;重复.more这段代码
.done:
retn
data1db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
db 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h
data2db 'Super blue fruit tech',0dh,0ah,0
rb 7C00h+512-2-$;fill up to the boot record signature
db 055h,0AAh;the signature itself


分享给朋友:

相关文章

Radasm 编辑器配置VC2010下的Opencv 环境。

Radasm 编辑器配置VC2010下的Opencv 环境。

Opencv 下载地址:https://opencv.org/releases.html备用下载地址1:https://blog.csdn.net/yanzi1225627/article/detai...

关于ch341驱动,联动3D打印机USB串口通讯.

关于ch341驱动,联动3D打印机USB串口通讯.

手上有个3D打印机,搬家的原因,好久没用.天气热了,打印温度很适合,正好可以使用.又过了一年.发现linux 版本内核已经升级,和原来的系统不一样了. 按照3D打印机的说明,和寻找它的程序,原来的方法...

linux 下的《仙剑奇侠传》

linux 下的《仙剑奇侠传》

以前的DOS游戏《仙剑奇侠传》是炙制人口的一个很容易上手的游戏。这个游戏流行了很多年。很多人在玩过多年以后,重温旧梦,回味游戏之中的情感。这个游戏再版了很多次了。现在linux 下也可以直接玩这个游戏...

关于编译器不愿意说的那些事。

关于编译器不愿意说的那些事。

计算机发展了好多年。当中也不泛有很多对程序的爱好。很多人不是专业水平,也不是在算法类中特别出众,就是喜欢而已。好像认为自己就只那个水平,或者为一些调试不通过发愁。可以说,实际上都不是你的错,是编译器的...

刚刚上手的一个汇编程序nasm。

刚刚上手的一个汇编程序nasm。

今天使用了masm32软件,总有使不上劲的感觉。因为intel 指令集很多都没有,自己想测试一下,一边翻资料,一边使用。windows 编程好用,但是指令不全,心里总是感觉差一点。又不是编大程序,只是...

编译文件的各种LIB文件分析

编译文件的各种LIB文件分析

玩计算机的都知道,计算机执行的是机器指令。机器指令是手工输入的,后来有了汇编语言。汇编语言很是方便,加了很多辅助符号帮助人们使用机器指令。很多重复的指令功能,就用宏和函数过程来反复使用。后来就有了C语...