主题:写测试视频存储区
下面程序是一个测试的程序,
1:设置显示模式为12H ,图形下640*480象素,16色
2:将11111111B写入 显示存储区的第2个字节, 地址为A000:0002
3: 将视频存储区的前600个字节写入ES段(ES段作为视频区的映像或暂存,调试中只申请了600字节的变量)
4:显示视频存储区(或映像区)的前20个字节,以2进制打印于屏幕上
5:按任意键退出程序
主要是为了观察存储区的变化,这里有个很麻烦的事情,就是在DEBUGE 调试里,很麻烦,
所以费了九牛二虎之力,才把这第一个位面的一些数据显示了出来
这里主要观察不到显示存储区的变化可能有几个原因不知道对不对
1:如果用DEBUG 调试, 它可能调用了BIOS的字符显示例程,肯定刷掉了你写进去的象素值
2:即使你不用DEBUG调试,你打算直接把数据从A000:0000的地方一个一个取出来,在打印出来
仍然调用了BIOS的显示例程,我试了,视频区仍然都是00
所以采用了刚刚写完象素就映像到备份的映像区里就是ES段里的存储区,然后对其进行显示操作
最后终于把第一个位面的前20个字节打印了出来,和实际写上去的象素内容一至。
在这种模式下一屏幕象素需要占用640*480*4个位 大概需要150K字节
A000段有64K,其中第一个位面存储了640*480=38400个字节,也就是所有屏幕上象素的第一个值
那么第二个位面的首地址是那里?第三个?第四个?
DATA SEGMENT ;data segment include test buffer and the croodinate in graphics mode
TEST_BUF DB 100 DUP (0)
CROOD DB 0,0 ;store char displayed coordinates
DATA ENDS
EXTRA SEGMENT ;ES is video buffer's reflex
REFLEX DB 600 DUP(0)
EXTRA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:EXTRA
MAIN PROC FAR
START:
MOV AX,DATA
MOV DS,AX
MOV AX,EXTRA
MOV ES,AX
MOV AL,12H ;set 12H video mode
CALL SEL_MOD ; call BIOS
CALL DRAW_RED ;draw some red pixel to first line
CALL STR_MEM ; save the values from video buffer
MOV AX,ES ; AX= seg address which will be displayed
MOV BX,0000H ; BX= offset address which will be displayed
MOV CX,20 ; BYTE number
CALL DIS_VGA_ADRS ;to display 20 BYTE by video buffer's reflex on screen
MOV AH,1 ;unusing
INT 21H
MOV AH,2
INT 21H
MOV AH,1
INT 21H
MOV AH,4CH
INT 21H
MAIN ENDP
;*********************************************************
;to select video model
;on entry:
; AL= display mode number
SEL_MOD PROC NEAR
PUSH AX
MOV AH,0
INT 10H ;call BIOS
POP AX
RET
SEL_MOD ENDP
;*********************************************
;_________________________________
;draw some red point on the first line of the screen
;
DRAW_RED PROC NEAR
PUSH ES
PUSH AX
PUSH SI
MOV AX,0A000H
MOV ES,AX
MOV SI,2
MOV AL,11111111B
MOV ES:[SI],AL
POP SI
POP AX
POP ES
RET
DRAW_RED ENDP
;___________________________________
;***************************************
;stroe the pixels in the video buffer's reflex
;mov the value bewteen A000:0000 and A000:FFFF to ES segment's memory
;
;***********************************
STR_MEM PROC NEAR
PUSH DS
PUSH ES
PUSH AX
PUSH SI
PUSH DI
PUSH CX
MOV AX,0A000H ;send 600 BYTES in video buffer to ES seg
MOV DS,AX
MOV AX,EXTRA
MOV ES,AX
MOV SI,0
MOV DI,0
MOV CX,600
REP MOVSB
POP CX
POP DI
POP SI
POP AX
POP ES
POP DS
RET
STR_MEM ENDP
1:设置显示模式为12H ,图形下640*480象素,16色
2:将11111111B写入 显示存储区的第2个字节, 地址为A000:0002
3: 将视频存储区的前600个字节写入ES段(ES段作为视频区的映像或暂存,调试中只申请了600字节的变量)
4:显示视频存储区(或映像区)的前20个字节,以2进制打印于屏幕上
5:按任意键退出程序
主要是为了观察存储区的变化,这里有个很麻烦的事情,就是在DEBUGE 调试里,很麻烦,
所以费了九牛二虎之力,才把这第一个位面的一些数据显示了出来
这里主要观察不到显示存储区的变化可能有几个原因不知道对不对
1:如果用DEBUG 调试, 它可能调用了BIOS的字符显示例程,肯定刷掉了你写进去的象素值
2:即使你不用DEBUG调试,你打算直接把数据从A000:0000的地方一个一个取出来,在打印出来
仍然调用了BIOS的显示例程,我试了,视频区仍然都是00
所以采用了刚刚写完象素就映像到备份的映像区里就是ES段里的存储区,然后对其进行显示操作
最后终于把第一个位面的前20个字节打印了出来,和实际写上去的象素内容一至。
在这种模式下一屏幕象素需要占用640*480*4个位 大概需要150K字节
A000段有64K,其中第一个位面存储了640*480=38400个字节,也就是所有屏幕上象素的第一个值
那么第二个位面的首地址是那里?第三个?第四个?
DATA SEGMENT ;data segment include test buffer and the croodinate in graphics mode
TEST_BUF DB 100 DUP (0)
CROOD DB 0,0 ;store char displayed coordinates
DATA ENDS
EXTRA SEGMENT ;ES is video buffer's reflex
REFLEX DB 600 DUP(0)
EXTRA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:EXTRA
MAIN PROC FAR
START:
MOV AX,DATA
MOV DS,AX
MOV AX,EXTRA
MOV ES,AX
MOV AL,12H ;set 12H video mode
CALL SEL_MOD ; call BIOS
CALL DRAW_RED ;draw some red pixel to first line
CALL STR_MEM ; save the values from video buffer
MOV AX,ES ; AX= seg address which will be displayed
MOV BX,0000H ; BX= offset address which will be displayed
MOV CX,20 ; BYTE number
CALL DIS_VGA_ADRS ;to display 20 BYTE by video buffer's reflex on screen
MOV AH,1 ;unusing
INT 21H
MOV AH,2
INT 21H
MOV AH,1
INT 21H
MOV AH,4CH
INT 21H
MAIN ENDP
;*********************************************************
;to select video model
;on entry:
; AL= display mode number
SEL_MOD PROC NEAR
PUSH AX
MOV AH,0
INT 10H ;call BIOS
POP AX
RET
SEL_MOD ENDP
;*********************************************
;_________________________________
;draw some red point on the first line of the screen
;
DRAW_RED PROC NEAR
PUSH ES
PUSH AX
PUSH SI
MOV AX,0A000H
MOV ES,AX
MOV SI,2
MOV AL,11111111B
MOV ES:[SI],AL
POP SI
POP AX
POP ES
RET
DRAW_RED ENDP
;___________________________________
;***************************************
;stroe the pixels in the video buffer's reflex
;mov the value bewteen A000:0000 and A000:FFFF to ES segment's memory
;
;***********************************
STR_MEM PROC NEAR
PUSH DS
PUSH ES
PUSH AX
PUSH SI
PUSH DI
PUSH CX
MOV AX,0A000H ;send 600 BYTES in video buffer to ES seg
MOV DS,AX
MOV AX,EXTRA
MOV ES,AX
MOV SI,0
MOV DI,0
MOV CX,600
REP MOVSB
POP CX
POP DI
POP SI
POP AX
POP ES
POP DS
RET
STR_MEM ENDP