微机课程设计(论文)通用微机发声程序的汇编设计.doc

上传人:laozhun 文档编号:2882080 上传时间:2023-03-01 格式:DOC 页数:37 大小:153.50KB
返回 下载 相关 举报
微机课程设计(论文)通用微机发声程序的汇编设计.doc_第1页
第1页 / 共37页
微机课程设计(论文)通用微机发声程序的汇编设计.doc_第2页
第2页 / 共37页
微机课程设计(论文)通用微机发声程序的汇编设计.doc_第3页
第3页 / 共37页
微机课程设计(论文)通用微机发声程序的汇编设计.doc_第4页
第4页 / 共37页
微机课程设计(论文)通用微机发声程序的汇编设计.doc_第5页
第5页 / 共37页
点击查看更多>>
资源描述

《微机课程设计(论文)通用微机发声程序的汇编设计.doc》由会员分享,可在线阅读,更多相关《微机课程设计(论文)通用微机发声程序的汇编设计.doc(37页珍藏版)》请在三一办公上搜索。

1、微型计算机课程设计 通用微机发声程序的汇编设计广东工业大学2002届工业工程2班伍健柱200201024222摘要:本文讲述了在微型计算机中利用可编程时间间隔定时器的通用发声程序设计,重点讲述了程序的发声原理,节拍的产生,按节拍改变的动画程序原理,并以设计一个简单的乐曲评分程序为引子,分析程序设计的细节。关键字:微机 8253 通用发声程序 动画技术 直接写屏1. 可编程时间间隔定时器8253在通用个人计算机中,有一个可编程时间间隔定时器8253,它能够根据程序提供的计数值和工作方式,产生各种形状和各种频率的计数/定时脉冲,提供给系统各个部件使用。本设计是利用计算机控制发声的原理,编写演奏乐曲

2、的程序。 在8253/54定时器内部有3个独立工作的计数器:计数器0,计数器1和计数器2,每个计数器都分配有一个断口地址,分别为40H,41H和42H.8253/54内部还有一个公用的控制寄存器,端地址为43H.端口地址输入到8253/54的CS,AL,A0端,分别对3个计数器和控制器寻址. 对8353/54编程时,先要设定控制字,以选择计数器,确定工作方式和计数值的格式.每计数器由三个引脚与外部联系,见教材第320页图9-1.CLK为时钟输入端,GATE为门控信号输入端,OUT为计数/定时信号输入端.每个计数器中包含一个16位计数寄存器,这个计数器时以倒计数的方式计数的,也就是说,从计数初值

3、逐次减1,直到减为0为止. 8253/54的三个计数器是分别编程的,在对任一个计数器编程时,必须首先讲控制字节写入控制寄存器.控制字的作用是告诉8253/54选择哪个计数器工作,要求输出什么样的脉冲波形.另外,对8253/54的初始化工作还包括,向选定的计数器输入一个计数初值,因为这个计数值可以是8为的,也可以是16为的,而8253/5的数据总线是8位的,所以要用两条输出指令来写入初值.下面给出8253/54初始化程序段的一个例子,将计数器2设定为方式3,(关于计数器的工作方式参阅教材第325330页)计数初值为65536. MOV AL,10110110B ;选择计数器2,按方式3工作,计数

4、值是二进制格式 OUT 43H,AL ; j将控制字送入控制寄存器 MOV AL,0 ;计数初值为0 OUT 42H,AL ;将计数初值的低字节送入计数器2 OUT 42H,AL ;将计数初值的高字节送入计数器2 在IBM PC中8253/54的三个时钟端CLK0,CLK1和CLK2的输入频率都是1.1931817MHZ. PC机上的大多数I/O都是由主板上的8255(或8255A)可编程序外围接口芯片(PPI)管理的.关于8255A的结构和工作原理及应用举例参阅教材第340373页.教材第364页的”PC/XT机中的扬声器接口电路”一节介绍了扬声器的驱动原理,并给出了通用发声程序.本设计正是

5、基于这个原理,通过编程,控制加到扬声器上的信号的频率,奏出乐曲的.2发声程序的设计下面是能产生频率为f的通用发声程序:MOV AL,10110110B;8253控制字:通道2,先写低字节,后写高字节;方式3,二进制计数OUT 43H,AL ;写入控制字MOV DX,0012H ;被除数高位MOV AX,35DEH ;被除数低位 DIV ID;求计数初值n,结果在AX中OUT 42H,AL;送出低8位MOV AL,AHOUT 42H,AL;送出高8位IN AL,61H;读入8255A端口B的内容MOV AH,AL ;保护B口的原状态ORAL,03H;使B口后两位置1,其余位保留OUT61H,AL

6、;接通扬声器,使它发声380x86的时间延迟 利用CPU循环执行一条或几条指令来产生延迟时间是最常用 的一种方法,但对8088/86,80286,80386,80486以及pentiumIV来说,由于它们的工作频率不同及有些指令执行周期的差异,执行同样的延迟程序,产生的延迟时间都不一样。为了建立一个与处理器无关的时间延迟,1BM采用了一种利用硬件产生时间延迟的方法,即通过监视端口61H的PB4,使PB4每15.08us触发一次,以产生一个固定不变的时间基准,。下面的WAITF程序就是一个产生N x 15.08us 时间延迟的程序。调用WALTF子程序时,CX寄存器必须装入15.08us的倍数N

7、。CX =15.08us的倍数WAITF PROC NEAR PUSH AXWALTF1: IN AL,61H AND AL,10H ;检测PB4的状态 CMP AL,AH ;是否发生变化 JE WAITF1 ;等待变化 MOV AH , AL ;存入新的PB4的状态 LOOP WAITF1 ;循环,直到CX 0为止 POP AX RETWAITF ENDP 当CX中的计数值N663时,调用WAITF子程序,可延迟10ms,若要延迟1s,可调用WAITF子程序100次,若要延迟0.5s,可调用WAITF子程序50次,依从类推,只要设置WAITF子程序的调用次数,就可获得所需的延迟时间。本程序还

8、使用了另外一种延时的方法,就是利用屏幕的垂直回扫周期来进行延时。微机的显示器工作时有一固定的刷新频率,这个频率由系统的显示控制器产生,既然有一固定的频率,我们就可以其作为基准来产生延时。在VGA显示卡上有一个寄存器可以被我们用来监视垂直回扫,这个寄存器我们称为VGA输入状态字寄存器,它在端口0x3da上,是个八位的寄存器,我们只对其中第四位感兴趣,当该位为1时,屏幕正在进行回扫,相邻的两次回扫之间的时间间隔即为屏幕的回扫周期。对于本程序,在演奏乐曲时是使用320*240,256色的vga显示模式,相应的垂直刷新频率为70hz,周期为1/70s等待垂直回扫的程序:WAITSCAN PROC NE

9、AR ;等待垂直回扫周期 PUSH DX PUSH AXWAITSCAN1: MOV DX,3DAH IN AL,DX AND AL,8H JZ WAITSCAN1 POP AX POP DX RETWAITSCAN ENDP这个子程序还可以用来消除动画的闪烁,使过渡更平滑。具体见后面章节。4 乐曲程序 (1)音调与频率和时间 的关系音调是按一定的高低,长短和强弱关系组成的音调。在一定乐曲中,每一个音符的音高和音长与频率和节拍有关。表给出音名和频率之间的关系。组成乐曲的每个音符的频率和持续时间是乐曲程序发声所需的两个数据。音符的频率可以查得。但实际上送入计数器2的是输入频率1.1193MHz与

10、音符频率相除的值。音符的持续时间是根据乐曲的速度及每个音符的节拍来确定的,在4/4(四四拍)中,四分音符为1拍,每小节4拍,音符持续4拍,二分音符持续2拍,四分音符持续1拍,八分音符持续半拍等。如果给全音符分配时间为1s ( 100 x 100ms )的时间,则二音符的持续时间为0.5s (50 x 10ms),四分音符 的持续时间为0.25s (25 x 10ms ),八分音符的持续时间为0.125s (12.5 x 10ms)音名频率(Hz)c130.8d146.8e164.8f174.6g196.0a220.0b246.9中央C261.7293.7329.6349.2392.0440.0

11、493.9523.3587.3659.1698.3783.9879.9987.71046.5(2) 演奏乐曲的程序 知道了音调与频率和时间的关系,就可以按照乐曲的曲谱降每个音符的频率和持续时间定义成两个数据表,咽喉编写程序依次取出表中的频率值和时间值,调用通用发生程序发生各种声音。 编写乐曲程序可以分四个步骤: 第一步,为演奏的乐曲定义一个频率表和一个节拍时间表。频率表中的数据可以从表中查到,节拍时间表的数据是延迟时间10ms的倍数; 第二步,分别将两个表中的偏移地址送入两个指针寄存器; 第三步,分别从两个表中取出频率值和音符的持续时间值,送入相应的寄存器中,供调用通用发声程序使用; 第四步,

12、调用通用发声程序发出音调。5动画技术本程序要实现的动画是根据乐曲的节拍来上下滚动和改变色调的渐变色动画。为了编程方便,我们使用VGA INT 13H模式。VGA INT 13H模式是一种工作在图形方式下的模式,它具有320X200的屏幕分辩率,同屏上可以显示256种颜色(超级任天堂和世嘉5代游戏机也只有256种颜色,当然ps,土星,ps2就不同了。),早期的许多游戏都是在这一图形方式下开发的(如大家非常熟悉的仙剑奇侠传、红色警戒、DOOM等),在这种模式下开发游戏具有编程简单、运行速度快、颜色丰富等特点。我们先来了解一下电脑显示器的工作原理和显示卡的结构。一显示器的工作原理目前在个人计算机上广

13、泛使用的是采用阴极射线管(CRT)的光栅扫描显示器,我们在屏幕上所看到的颜色是由电子枪发出的电子束打在CRT屏幕背面的荧光层上的点形成的,通过控制点的亮度可以产生不同的颜色。电子束不断地从左到右、从上到下扫描整个屏幕,使屏幕显示出图案,电子束以大约每秒70次的速率在屏幕上重画这一图案,这个过程称为显示刷新或屏幕刷新,具体的扫描频率依赖于所用的显示适配器(又称为显示卡)。电子束从屏幕的左上角开始向右扫描,到达屏幕的右边缘后,电子束被关闭(水平断开),接着它又迅速地返回到屏幕的左边缘(水平回扫)开始进行下一行水平方向的扫描,在完成全部的水平方向的扫描后,电子束在屏幕的右下角结束,此时电子束被关闭(

14、垂直断开),接着又迅速地返回到屏幕的左上角(垂直回扫),开始下一屏扫描。电子束就是这样周而复始地扫描整个屏幕。显示器在两种方式下工作:文本方式和图形方式,电脑游戏一般在图形方式下进行。 二显示器的坐标系统计算机屏幕上的坐标与我们通常使用的直角坐标系不同,坐标原点(0,0)在屏幕的左上角,向右是水平方向的坐标,向下是垂直方向的坐标,且坐标没有负值。三显示卡的结构显示器上的显示卡负责将图形显示在屏幕上。显示存储器中存放着在屏幕上显示的图像数据,显示卡硬件不停地将显存中的内容显示在屏幕上。显示存储器实际上是安装在显示卡上的一块或几块大规模集成电路,其容量有1M、2M、4M、8M等,在DOS下我们可以

15、访问的内存只有1MB空间(这就是DOS的局限性所在),地址从00000H到FFFFFH,这段内存根据用途又分为不同的块,系统分配给图形缓冲区(显示存储器)的地址在A0000H到BFFFFH之间,大小为128KB,其中,VGA占用了A0000H到AFFFFH段,共64KB,这段地址是内存映射地址,供我们访问显示存储器用。在VGA 13H图形模式下,显示内存使用A0000H到AF9FFH的一段线性内存空间,每个字节表示一个点,对应屏幕上的一个像点,320*200的屏幕分辨率共需要64000个字节,刚好64KB,因为一个字节可以表示的最大整数值为256,所以每个像点就可以表示256种颜色。四设置视频

16、模式画图以前必须使屏幕工作在图形方式,这就要设置屏幕的视频模式。设置视频模式有许多种方法,其中调用视频BIOS功能是最简单的一种,通过调用BIOS中断10h的服务程序,可以很方便地设置屏幕模式。调用方法是将值0放入ah寄存器,显示模式放入al寄存器中,然后调用int 10h。设置视频模式的子程序: MOV AH,0 MOV AL,13H ;初始化屏幕模式 INT 10H五在屏幕上画点由于显示存储器是线性排列的,每个像点用一个字节来表示,所以对像点寻址非常容易,像点在显示内存中的偏移地址可由这个公式确定:y*320+x,其中,y是像点在垂直方向的坐标,x是水平方向的坐标,320是屏幕的宽度。有了

17、像点的偏移地址,然后加上显示内存的首地址即可得到像点在显示内存中的绝对地址。六设置颜色寄存器我们知道VGA显示卡具有显示256种颜色的能力,每种颜色能够用一个0-255之间的数值来表示,那么这些数值与我们在屏幕上实际见到的颜色之间有什么关系呢?其实这些数值只是VGA显示卡上的颜色寄存器的索引值,颜色寄存器里才保存了屏幕上颜色的真实值。VGA显示卡上有一个包含256个单元的颜色寄存器(又称为调色板),每个单元由三部份组成,这三部份分别代表颜色中的红、绿、蓝三种成份(显示器就是用这三种成份来组成任何我们所看到的颜色),用三个字节表示,颜色寄存器一共有768个字节(3*256=768)。当我们要在屏

18、幕上显示某种颜色时,显示卡硬件就根据颜色的索引值在颜色寄存器中查找,找到后再从相应单元中取出颜色值显示在屏幕上,这个过程与画家使用调色板相似,颜色寄存器相当于调色板,颜色寄存器中的单元相当于调色板上的色格,在色格中装有预先调好的颜色,当画家需要用某种颜色作画时,就从装有那种颜色的色格中把颜色取出来。例如,我们要显示颜色索引值为30的颜色,显示卡硬件就去查找颜色寄存器的第30单元,30单元位于距颜色寄存器首址3*30=90处(因为每个单元有三个字节),然后取出90处记录有红、绿、蓝三种成份的三个字节作为在屏幕上显示的色彩信号。但是实际上每个字节只用了六位来表示颜色,其它两位没用,这六位表示的数的

19、值域为0-63,所以每种颜色(红、绿、蓝)成份具有64种亮度的表现能力,三种颜色成份组合共可以产生64*64*64=262,144种颜色(VGA 13H模式从这262,144种颜色中取出256种在同一屏幕上显示)。我们可以通过事先设置颜色寄存器的值来使用我们自己的颜色。 设置颜色寄存器有多种方法,如调用BIOS功能,但是这种方法速度比较慢,游戏设计中通常采用直接访问VGA显示卡的I/O端口的方法来快速设置颜色寄存器,我们只需访问四个I/O端口就可以完成设置颜色寄存器的工作。这四个端口分别是: 3c6H、3c7H、3c8H和3c9H。端口3c6H称为调色板屏蔽寄存器,用来屏蔽所要求的调色板寄存器

20、的位,如果你在这个寄存器中放入0ffh,你就可以通过调色板索引寄存器3c7H和3c8H(一个用于读,一个用于写)访问任何你希望访问的颜色寄存器,端口3c9H称为调色板数据寄存器,红、绿、蓝三种成份就是通过它进行读写(颜色值要读或写三次)。在本程序中,程序先开辟一768字节的调色板缓冲区,之后调用一个子程序将缓冲区的数据输出到显卡的调色板中,程序如下:LOAD_PALETTE PROC PUSH DX ; 把调色板缓冲区中的数据输出到显卡调色板中 PUSH AX push cx push si MOV DX,3C6H ;INIT MASK REG MOV AL,0FFH OUT DX,AL MO

21、V CX,0 mov bx,0LOAD_LOOP: MOV DX,3C8H MOV AL,Cl OUT DX,AL mov dx,3c9h mov al,palettebx inc bx out dx,al mov al,palettebx inc bx out dx,al mov al,palettebx inc bx out dx,al inc cx cmp cx,254jne LOAD_LOOPpop si pop cx pop ax pop dxret LOAD_PALETTE ENDP七。渐变色的产生给出两种不同的颜色,计算其产生的渐变,关键在于计算它们的过渡值。譬如下面两个颜色(为

22、RGB值):红(255,0,0)黄(255,255,0)其中间过渡色的值在以下范围:(255,x,0),x等于0到255。X在0,255的范围均匀分布,x从0一直增大到255。又譬如:橙黄(255,210,0)草绿(121,253,0)其中间过度色的值为(x,y,0),x等于255到121,y等于210到253。X,y 各自在自己的取值范围内均匀分布。X从255逐渐减少到121,y从210逐渐增大到253。对于VGA INT 13H模式,RGB的最大值均为63.下面给出产生渐变色的子程序,产生的渐变色值放在调色板缓冲区,并最终输出到显卡中去。CREATE_PALETTE PROC NEAR ;

23、用新参数,在调色板缓冲区中生成新的调色板值 PUSH DX PUSH AX PUSH CX PUSH BX push di push si push bp mov al,palette_parameter2 ;求渐变时三元色的增量,;分别放在red_increment,green_increment,blue_incremet中 mov bl,palette_parameter1 sub al,bl mov bl,100 ;将浮点运算变为定点运算 imul bl mov bl,127 idiv bl cbw mov red_increment,ax mov al,palette_paramet

24、er2+1 ;求渐变时三元色的增量,;分别放在red_increment,green_increment,blue_incremet中 mov bl,palette_parameter1+1 sub al,bl mov bl,100 ;将浮点运算变为定点运算 imul bl mov bl,127 idiv bl cbw mov green_increment,ax mov al,palette_parameter2+2 ;求渐变时三元色的增量,;分别放在red_increment,green_increment,blue_incremet中mov bl,palette_parameter1+2

25、 sub al,bl mov bl,100 ;将浮点运算变为定点运算 imul bl mov bl,127 idiv bl cbw mov blue_increment,ax mov bx,0 mov ax,0 mov al,palette_parameter1 mov palettebx,al inc bx mov al,palette_parameter1+1 mov palettebx,al inc bx mov al,palette_parameter1+2 mov palettebx,al inc bx mov cx,126 mov al,palette_parameter1 mov

26、 dl,100 mul dl mov si,ax mov al,palette_parameter1+1 mov dl,100 mul dl mov di,ax mov al,palette_parameter1+2 mov dl,100 mul dl mov bp,axc_loop: mov ax,si mov dx,red_increment ;根据增量,对三元色进行加法计算,以产生渐变 add ax,dx mov si,ax mov dl,100 div dl mov palettebx,al inc bx mov ax,di mov dx,green_increment ;根据增量,对

27、三元色进行加法计算,以产生渐变 add ax,dx mov di,ax mov dl,100 div dl mov palettebx,al inc bx mov ax,bp mov dx,blue_increment ;根据增量,对三元色进行加法计算,以产生渐变 add ax,dx mov bp,ax mov dl,100 div dl mov palettebx,al inc bx loop c_loop;*计算下两个渐变 mov al,palette_parameter3 ;求渐变时三元色得增量 mov bl,palette_parameter2 sub al,bl mov bl,100

28、 imul bl mov bl,126 idiv bl cbw mov red_increment,ax mov al,palette_parameter3+1 ;求渐变时三元色得增量 mov bl,palette_parameter2+1 sub al,bl mov bl,100 imul bl mov bl,126 idiv bl cbw mov green_increment,ax mov al,palette_parameter3+2 ;求渐变时三元色得增量 mov bl,palette_parameter2+2 sub al,bl mov bl,100 imul bl mov bl,

29、126 idiv bl cbw mov blue_increment,ax mov bx,381 mov ax,0 mov al,palette_parameter2 mov palettebx,al inc bx mov al,palette_parameter2+1 mov palettebx,al inc bx mov al,palette_parameter2+2 mov palettebx,al inc bx mov cx,125 mov al,palette_parameter2 mov dl,100 mul dl mov si,ax mov al,palette_paramete

30、r2+1 mov dl,100 mul dl mov di,ax mov al,palette_parameter2+2 mov dl,100 mul dl mov bp,axc_loop2: mov ax,si mov dx,red_increment add ax,dx mov si,ax mov dl,100 div dl mov palettebx,al inc bx mov ax,di mov dx,green_increment add ax,dx mov di,ax mov dl,100 div dl mov palettebx,al inc bx mov ax,bp mov d

31、x,blue_increment add ax,dx mov bp,ax mov dl,100 div dl mov palettebx,al inc bx loop c_loop2 pop bp pop si pop di POP BX POP CX POP AX POP DX RETCREATE_PALETTE ENDP八动画的产生本程序先在屏幕画200条水平的直线,每条直线的索引颜色值递增,增量为1。之后不断改变显卡中调色板中的颜色索引序列,就可以达到颜色上下滚动的目的了。具体的程序参看源程序清单。九按照音乐节拍改变的动画本程序中,动画是随着音乐的节拍而产生色调和方向的变化的。具体参看源

32、程序清单。十动画的平滑技术(即屏幕闪烁的消除)当我们直接在显示缓冲区内绘图时,屏幕上往往会产生闪烁或类似裁剪的现象,这是为什么呢?这是因为人的眼睛有惰性,当人眼看东西时,看过的东西的影像会在人的眼睛里停留一段很短的时间,大约为124秒,当图像在一个时间间隔中被更新时,如果更新的时间长于124秒,看到的图像就会产生闪烁,124秒是一个人能够看出视觉变化的最少时间量。产生屏幕闪烁还有另外一个原因,就是我们绘制图像时没有与视频显示完全同步,VGA视频硬件以大约每秒70次的速率刷新屏幕,绘制图像过程如果不在一个刷新周期内完成的话,屏幕也会产生闪烁现象,因为可能会出现一幅图像还没有绘制完就被显示出来的情

33、况。如何避免屏幕出现闪烁呢?一般有二种方法:一是使图像的绘制过程在屏幕的一个刷新周期内进行。二是采用双缓冲的方法。在垂直回扫周期内视频缓冲区不会被视频硬件访问,如果我们改变了视频缓冲区,也要等到下一帧才能看到结果,更新视频缓冲的最佳时机是它没有被访问的时候-垂直回扫周期内。为此我们必须找到检测垂直回扫开始的方法,并且用检测的结果使视频缓冲更新和屏幕刷新同步。在VGA显示卡上有一个寄存器可以被我们用来监视垂直回扫,这个寄存器我们称为VGA输入状态字寄存器,它在端口3dah上,是个八位的寄存器,我们只对其中第四位感兴趣,当该位为1时,屏幕正在进行回扫,该位为0时,没有回扫。等待垂直回扫的程序:WA

34、ITSCAN PROC NEAR ;等待垂直回扫周期 PUSH DX PUSH AXWAITSCAN1: MOV DX,3DAH IN AL,DX AND AL,8H JZ WAITSCAN1 POP AX POP DX RETWAITSCAN ENDP函数从端口3dah取出一个字节,然后将这个字节与值8h进行与运算,运算结果如果为1则回扫过程开始。如前所述,对垂直回扫计数也可用来给程序定时。6程序测试本程序用未来汇编1.0(编译内核为TASM 4.1)编译运行。分别在Pentium 100,PentiemIII 733E, CeleronIII 1100A, Celeron D 2.53B的

35、硬件环境,Operation System为 DOS 6.22, PDOS95, Windows 95, Windows 98 SE, CCDOS, Windows2000 Advance Server, WindowsXP的软件环境下均顺利运行,动画流畅平滑,色彩绚丽自然,乐曲音调基本准确。在低至100M主频的系统也能流畅运行,速度与在2.53G主频的系统下运行速度无明显差别。源程序清单;*; 通用微机发声程序及动画显示;Power BY WJZ; 编译环境 : 未来汇编1.0 编译内核: TASM 4.1; COPYRIGHT (C) 2005; 本程序为2004学年度,广东工业大学200

36、2届工业工程2班; 伍健柱 的微机课程设计作业,引用须保留版权信息;*DATA SEGMENT PALETTE DB 764 DUP(?) ;调色板缓冲 palette_top db ? palette_parameter1 db 3 dup(?) ;产生渐变色的三个参数 palette_parameter2 db 3 dup(?)palette_parameter3 db 3 dup(?) red_increment dw ? ;生成渐变色的临时参数,分别为红,绿,蓝的增量 green_increment dw ? blue_increment dw ? ROCK_DIRECT DB 0 ;

37、动画滚屏的方向 COLOR DB 63,63,0,0,63,10 ;渐变色的色调值 DB 63,0,0,63,63,0 DB 38,63,0,63,63,63 DB 0,49,61,63,63,63 DB 0,0,63,0,63,63 DB 63,27,0,63,63,63 DB 63,0,56,63,0,0 DB 63,53,0,30,63,0COLOR_POINT DW 0 ; 渐变色的色调值指针 mus1 dw 196,196,330,294,262,196 ; 第一支乐曲的音调值 dw 3 dup(196),330,294,262,220 dw 220,220,349,330,294,247 dw 247,392,392,349,294,330 dw 196,196,330,294,262,196 dw 196,196,330,294,262,220 dw 220,220,349,330,294,392,392,392 dw 392,4

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号