首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么在VGA模式下写入图形内存的写入模式不发生变化?

为什么在VGA模式下写入图形内存的写入模式不发生变化?
EN

Stack Overflow用户
提问于 2022-07-14 09:02:34
回答 1查看 77关注 0票数 0

我试图用NASM绘制DOSBOX中VGA图形的屏幕。我的代码可以很好地写到一个黑色屏幕上,但是如果我编辑一个已经是特定颜色的像素,输出的颜色将是与我的新颜色相同的前一个颜色ORed。例如,如果我填充一个红色的屏幕,然后再填充它作为蓝色它最后的屏幕将不是蓝色,但它将是一个洋红色。

下面是我的代码,它应该填充屏幕蓝色,然后是绿色,而是填充屏幕蓝色,然后再用绿色替换蓝色内存,从而形成一个填充屏幕的屏幕。我在DOSBOX中看到了这种情况,减缓了cpu的速度。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
org 100h
section .text
start:
    mov ax, 4F02h
    mov bx, 102h
    int 10h       ; enter 800x600 16 color VGA mode
    push 0x01     ; blue
    call fill_screen
    push 0x2      ; green
    call fill_screen
    jmp $

fill_screen:
    ; multiply screen width by height then divide by 8 to get number of times to repeat write operation, push to stack
    mov ax, [screen_width]
    mov dx, [screen_height]
    mul dx
    mov cx, 8
    div cx
    push ax

    ; point es to video memory
    mov ax, 0A000h
    mov es, ax

    pop cx  ; times to repeat write operation
    pop dx  ; return address
    pop ax  ; color 
    push dx ; put return address back on stack
    
    mov dx, 03c4h ; register selection port
    shl ax, 8     ; color is one byte, it was in al but we need it in ah so shift left one byte
    mov al, 02h   ; map mask
    out dx, ax    ; write all the bitplanes
    xor di, di    ; video memory pointer to start
    mov ax, 0ffh  ; write to every pixel
    rep stosb
    ret

section .data
    screen_width dw 320h
    screen_height dw 258h

这里在第5节中说,您可以更改写模式以替换,或者,xor,或者通过写到端口03CFh。它们包括切换到XOR模式的示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mov ax,1803h
mov dx,03CEh
out dx,ax

当我在第6行(int 10h)之后添加它时,什么都不会发生,并且代码的输出仍然是teal的。由于蓝色或绿色与蓝色XOR绿色相同,所以我将绿色输入更改为洋红(请执行第9行push 0x5)。输出现在是洋红色,这意味着内存仍然处于OR模式,而不是在XOR模式下。

下面是最后的测试代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
org 100h
section .text
start:
    mov ax, 4F02h
    mov bx, 102h
    int 10h       ; enter 800x600 16 color VGA mode

    ; switch to XOR write mode (?)
    mov ax, 1803h
    mov dx, 03CEh
    out dx, ax

    push 0x01 ; blue
    call fill_screen
    push 0x5 ; magenta
    call fill_screen
    jmp $

fill_screen:
    ; multiply screen width by height then divide by 8 to get number of times to repeat write operation, push to stack
    mov ax, [screen_width]
    mov dx, [screen_height]
    mul dx
    mov cx, 8
    div cx
    push ax

    ; point es to video memory
    mov ax, 0A000h
    mov es, ax

    pop cx  ; times to repeat write operation
    pop dx  ; return address
    pop ax  ; color 
    push dx ; put return address back on stack

    mov dx, 03c4h ; register selection port
    shl ax, 8     ; color is one byte, it was in al but we need it in ah so shift left one byte
    mov al, 02h   ; map mask
    out dx, ax    ; write all the bitplanes
    xor di, di    ; video memory pointer to start
    mov ax, 0ffh  ; write to every pixel
    rep stosb
    ret

section .data
    screen_width dw 320h
    screen_height dw 258h

如何解决这个问题,从而进入不同的写入模式?是否有不同的更好的方式来写入视频内存,而不是使用我应该使用的写入模式?如何进入替换模式?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-14 14:22:19

关于VGA硬件的一些参考:硬件https://web.stanford.edu/class/cs140/projects/pintos/specs/freevga/vga/vgamem.htm

首先,XOR模式(和其他模式)不使用已经存在于视频内存中的数据的XOR。它们使用锁存寄存器进行异或,这些寄存器在从视频存储器读取时加载。锁存寄存器保持其值,直到从视频内存中读取另一个值为止。如果您不从视频内存中读取,那么锁存寄存器有一个未定义的值。

要保持正常模式(NOP模式),只需将模式设置为0:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mov ax,0003h
mov dx,03CEh
out dx,ax

另外,当写入03c4h/reg 2时,您设置了一个掩码,它将应用于对视频内存的所有写入,过滤您所写的每一个位。将掩码设置为0Fh将允许按预期写入所有位。如果您不使用掩码值0Fh (这是您的情况,而是用您的颜色填充它),那么掩码的0位将从锁存寄存器中取出,因为您没有读取这些寄存器。

若要编写没有掩蔽的颜色,请将掩码设置为0Fh,并编写实际颜色而不是FFh:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mov dx,03C4h
mov ax,0F02h
out dx,ax
mov es:[di], <color> ; example write

如果希望对每个像素使用XOR和掩码操作,则需要在每次写入之前正确地填充闩锁,方法是执行虚拟读取:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mov bl, es:[di] ; ignore bl if not needed
mov es:[di], <color> ; example write with VGA operations

请注意,使用bl并自己执行xor/掩码的替代方法并不复杂。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72984211

复制
相关文章
Influxdb Cluster下的数据写入
3.2 调用w.MetaClient.CreateShardGroup, 如果ShardGroup存在直接返回ShardGroup信息,如果不存在创建,创建过程涉及到将CreateShardGroup的请求发送给MetadataServer并等待本地更新到新的MetaData数据;
扫帚的影子
2018/12/12
1.2K0
最后写入胜利(丢弃并发写入)
实现最终收敛的一种方案,每个副本总存储最新值,允许覆盖并抛弃旧值。假定每个写请求都最终同步到所有副本,只要确定哪个写入是最新,则副本就能最终收敛到相同值。
JavaEdge
2022/08/01
2.4K0
最后写入胜利(丢弃并发写入)
硬盘被写入数据后重量会变化么?
这个问题还真是有点烧脑。我们不妨先看看高中物理学过的极板电容器被充了电,其质量是否有变化。与其说给电容充电,不如说是给电容“充能”,本侧负电荷越多,对面的正电荷也相应越多,整个电容其实是电中性的。给电容充电所使用的电源的负极输出了假设1000个负电荷到电容负极板上,那么电源的正极就要相应的吸纳1000个负电荷,因为电流在电路中是整体移动的,不存在某些路段电流高某些路段电流低的情况。那么电源正极吸纳的1000个负电荷是从哪里来的?当然是从电容的正极板上吸过来的,所以电容正极板上自然就露出了1000个正电荷,这样在电容两个极板之间就产生了电势差,相当于正极板贡献了1000个电子给负极板。
冬瓜哥
2019/06/10
8360
硬盘被写入数据后重量会变化么?
【Python】文件操作 ⑤ ( 文件操作 | 以只读模式向已有文件写入数据 | 以追加模式向已有文件写入数据 | 以追加模式打开一个不存在的文件 )
使用 write 函数向已有文件写入数据 , 会清空该文件中的数据 , 代码展示如下 :
韩曙亮
2023/10/11
5530
【Python】文件操作 ⑤ ( 文件操作 | 以只读模式向已有文件写入数据 | 以追加模式向已有文件写入数据 | 以追加模式打开一个不存在的文件 )
BufferedWriter写入
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/132801.html原文链接:https://javaforall.cn
全栈程序员站长
2022/08/14
8350
Android 9.0 飞行模式下WiFi状态变化
在Android 9.0 中,AirPlaneMode与WiFi的原生设定是这样的:
用户7557625
2020/07/15
1.6K0
追加模式创建的FileOutputStream获取的FileChannel设置position不影响写入位置
其实position方法调用成功了,感兴趣的可以跟踪下FileChannelImpl类的position方法:
johnhuster的分享
2022/03/29
7000
图片介质受写入保护_写入保护
最近使用U盘,突然不能正常使用了,在U盘内新建文件夹,提示“介质受写入保护”无法创建文件,赶紧网上查找解决办法。查找的结果比解释比较全面的就是:
全栈程序员站长
2022/11/17
6.3K0
图片介质受写入保护_写入保护
wordpress速度优化-静态页写入内存
昨天博客加了WP Super Cache缓存插件,速度提升明显。使用这类插件可以将PHP动态页面在首次访问时生成html静态页面并存储在硬盘中,当其他访客再次访问时直接读取该静态页面,这样不需要再次通过PHP生成动态页面也不需要再从数据库中读取数据,大幅降低系统资源消耗,且大幅提升了页面打开速度。
AlexTao
2019/07/16
1.8K0
wordpress速度优化-静态页写入内存
文件的读取写入
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
bering
2019/12/03
2.7K0
Go map[int64]int64 写入 redis 占用多少内存
我们在系统设计面试或者在实际工作中,免不了要进行一些估算。之前的文章里讲过一些技巧,今天来个实战。
梦醒人间
2021/11/18
1.3K0
Go map[int64]int64 写入 redis 占用多少内存
内存吞金兽(Elasticsearch)的那些事儿 -- 写入&检索原理
客户端写入一条数据,到Elasticsearch集群里边就是由协调节点来处理这次请求:
房上的猫
2021/08/31
6390
内存吞金兽(Elasticsearch)的那些事儿 -- 写入&检索原理
写入Ring Buffer
原文地址:http://mechanitis.blogspot.com/2011/07/dissecting-disruptor-writing-to-ring.html​ 作者是 Trisha Gee, LMAX 公司的一位女工程师。 这是 Disruptor 全方位解析(end-to-end view)中缺少的一章。当心,本文非常长。但是为了让你能连在一起联系上下文的阅读,我还是决定把它们写进一篇博客里。 本文的 重点 是:不要让 Ring 重叠;如何通知消费者;生产者一端的批处理;以及多个生产者如何协
张善友
2018/01/19
1.5K0
写入Ring Buffer
文件操作——写入
前面我们说到了文件的读取,读取的文件是我们手动创建的txt文本文档,VBA也是可以对文件进行写操作的。
xyj
2020/07/28
2.9K0
文件操作——写入
elasticsearch 写入优化
不考虑搜索实时性,数据的可靠性,追求高性能写入性能。现实情况下,有没有这种场景呢?有。如生产数据初始化、割接、拷贝就这种典型场景,可以忽略前面2个因素,因为更快写入性能可以加快工作的完成,减少系统终端时间。以下这张脑图,综合各方面的资料,系统全面地从13个维度整理相关要素。当然实际工作中可以根据具体情况进行权衡抉择。图片
用户1233856
2022/08/10
6030
java写入文件
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/106359.html原文链接:https://javaforall.cn
全栈程序员站长
2022/06/30
2K0
Python逐行写入
# -*-coding:utf-8-*-import os# 写之前,先检验文件是否存在,存在就删掉if os.path.exists("dest.txt"): os.remove("dest.txt")# 以写的方式打开文件,如果文件不存在,就会自动创建file_write_obj = open("dest.txt", 'w')var = "adfss"file_write_obj.writelines(var)file_write_obj.write('\n')file_write_obj.clo
狼啸风云
2020/07/26
2.4K0
lua文件写入
mode 作用 r 读,文件不存在则报错 w 写,若文件存在则覆盖重写,若文件不存在则新建 a 写,若文件不存在,则新建;如果文件存在,则在文件尾追加要写的内容 r+ 读写,文件不存在则报错 w+ 读写,若文件存在则覆盖重写,若文件不存在则新建 a+ 读写,若文件不存在,则新建;如果文件存在,则在文件尾追加要写的内容 b 以二进制模式打开文件 file=io.open("/test.txt","r") io.input(file)-- 设置默认输入文件 print(io.read()) io.close(
司夜
2023/03/31
2.1K0
Flink on YARN模式下TaskManager的内存分配探究
该作业启动了10个TaskManager,并正常运行。来到该任务的Web界面,随便打开一个TaskManager页面,看看它的内存情况。
王知无-import_bigdata
2021/06/01
1.4K0
Flink on YARN模式下TaskManager的内存分配探究
点击加载更多

相似问题

在发布模式下写入Debug

22

为什么'WriteLine()‘函数不在睡眠模式下写入?

13

绘制VGA模式下的字符

13

文件仅在调试模式下写入

116

在附加模式下写入avro文件时更改其模式

114
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文