找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 6964|回复: 9

【DOS】16位汇编实现DOS下256色图形文本模式旋转的菱形的表示

[复制链接]
发表于 2014-1-31 23:14:24 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
Diamond.gif
text.png
下面的源码只是图形模式的。文本模式的源码请看附件。
  1. %define SCRWIDTH        320                        ;屏幕横向分辨率
  2. %define SCRHEIGHT        200                        ;屏幕纵向分辨率
  3. %define DIAMONDSIZE        50                        ;菱形的“半径”
  4. %define TURNSPEED        0.001                ;每帧转动弧度,必须为浮点数

  5. start:
  6. mov ax,0x13                                ;功能0,模式0x13:图形模式,256色,320x200分辨率
  7. int 0x10                                ;进入图形模式

  8. xor ax,ax                                ;改写中断向量表
  9. mov ds,ax
  10. cli
  11. mov word[0x1C*4],TimerINT        ;新的时钟中断
  12. mov [0x1C*4+2],cs
  13. sti
  14. mov ax,cs
  15. mov ds,ax

  16. mov ax,0xA000                        ;显存
  17. mov es,ax

  18. finit                                        ;初始化FPU
  19. Show:                                        ;开始单帧渲染
  20. ;hlt                                        ;等待一次中断。hlt会引起DOSBOX异常
  21. fwait

  22. ;取得时间
  23. mov al,0x06                                ;中断计时器值以便于读取
  24. out 0x43,al
  25. in al,0x40                                ;读取计时器低位
  26. mov ah,al
  27. in al,0x40                                ;读取计时器高位
  28. xchg ah,al                                ;交换高低位
  29. not ax                                        ;得到计时器时钟数
  30. mov [Time.Low],ax
  31. fild qword[Time]                ;读时钟计数
  32. fcom qword[Time.Old]        ;比较旧的时间值
  33. fstsw ax
  34. fwait
  35. sahf
  36. ja .TimeOK                                ;当新取得的时钟计数比旧的低时,更正时钟计数
  37. inc dword[cs:Time.High]
  38. fst st0
  39. fild qword[Time]                ;重新加载正确的时间
  40. fwait
  41. .TimeOK:
  42. fst qword[Time.Old]                ;将已经算出的时间存储起来,用于下一轮比较
  43. fmul qword[C_SPEED]                ;转动速度
  44. fdiv qword[CrystalFreq]        ;晶振频率
  45. ;得到角度

  46. fld st0                                        ;复制“角度”
  47. fcos                                        ;求“角度”余弦
  48. fst qword[Matrix.X_X]        ;一个存到矩阵的X_X
  49. fstp qword[Matrix.Y_Y]        ;一个存到矩阵的Y_Y
  50. fsin                                        ;求“角度”正弦
  51. fst qword[Matrix.X_Y]        ;存到矩阵的X_Y
  52. fchs                                        ;求反
  53. fstp qword[Matrix.Y_X]        ;存到矩阵的Y_X

  54. fild dword[C_HALFSCRHEIGHT]
  55. fchs                                        ;Y
  56. mov cx,SCRHEIGHT
  57. xor di,di
  58. .VLoop:
  59.         fwait                                ;等FPU处理好
  60.         fld1
  61.         fadd                                ;Y+=1.0;
  62.         fild dword[C_HALFSCRWIDTH]
  63.         fchs                                ;X
  64.         push cx
  65.         mov cx,SCRWIDTH
  66.         .HLoop:
  67.                 fld1
  68.                 fadd                        ;X+=1.0;
  69.                 fld st1
  70.                 fmul qword[Matrix.X_Y]
  71.                 fld st1
  72.                 fmul qword[Matrix.X_X]
  73.                 fadd
  74.                 fabs                        ;NewX=(X*m11+Y*m12)
  75.                 fistp dword[NewX]
  76.                
  77.                 fld st1
  78.                 fmul qword[Matrix.Y_Y]
  79.                 fld st1
  80.                 fmul qword[Matrix.Y_X]
  81.                 fadd
  82.                 fabs                        ;NewY=(X*m21+Y*m22)
  83.                 fistp dword[NewY]

  84.                 fwait                        ;等FPU处理好

  85.                 xor al,al
  86.                 cmp dword[NewX],DIAMONDSIZE
  87.                 ja .OutOfStupidDiamond
  88.                 cmp dword[NewY],DIAMONDSIZE
  89.                 ja .OutOfStupidDiamond
  90.                 mov al,[NewX]
  91.                 add al,[NewY]        ;AL为颜色值,设置AL为调色板颜色
  92.                 .OutOfStupidDiamond:
  93.                 stosb                        ;输出一个像素
  94.         loop .HLoop
  95.         pop cx
  96.         fstp st0                        ;保护浮点堆栈
  97. loop .VLoop
  98. fstp st0                                ;保护浮点堆栈
  99. jmp Show

  100. NewX dd 0
  101. NewY dd 0
  102. C_HALFSCRWIDTH dd SCRWIDTH/2
  103. C_HALFSCRHEIGHT dd SCRHEIGHT/2
  104. C_SPEED dq TURNSPEED

  105. Matrix:                ;旋转变换矩阵
  106. .X_X dq 1.0        ;矩阵X轴
  107. .X_Y dq 0.0
  108. .Y_X dq 0.0        ;矩阵Y轴
  109. .Y_Y dq 1.0

  110. Time:
  111. .Low dw 0        ;时间
  112. .High dd 0        ;时钟中断计数
  113. .Top dw 0        ;8字节对齐
  114. .Old dq 0        ;旧的时间

  115. CrystalFreq dq 1193.182

  116. TimerINT:
  117. inc dword[cs:Time.High]
  118. iret
复制代码
完整源码和编译器,回复后可见。
游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

发表于 2014-3-26 16:35:54 | 显示全部楼层
lz好厉害
回复

使用道具 举报

 楼主| 发表于 2015-9-18 21:40:58 | 显示全部楼层
已更新,提升了计时器精度。

大家可以从源码中看到我是怎么做浮点数比较的。
其实浮点数比较有很多种方法。
1、fcom之后,用fstsw将状态字写入ax,然后用sahf将ah的值写入eflags,之后就可以用jcc等条件判断指令了。
2、直接用fcomi,然后jcc等条件判断指令。
3、用两个待比较的浮点数做减法,然后将结果用fst存入内存,再判断这个存储的值的最高位是否为1——是的话第一个数比第二个数小。一定不要忘了fwait,否则FPU还没来得及写入数字,你就从内存取值了。
回复 赞! 靠!

使用道具 举报

发表于 2017-11-12 20:57:16 | 显示全部楼层
666666666666
回复 赞! 靠!

使用道具 举报

发表于 2017-11-15 20:39:57 | 显示全部楼层
16位汇编实现DOS下256色图形文本模式旋转的菱形的表示
回复 赞! 靠!

使用道具 举报

发表于 2018-1-25 10:53:59 | 显示全部楼层
     
回复 赞! 靠!

使用道具 举报

发表于 2018-1-27 09:13:45 | 显示全部楼层
厉害                              
回复 赞! 靠!

使用道具 举报

发表于 2018-9-8 11:02:51 | 显示全部楼层
哇好厉害,还是有好多指令不认识,好在有注释
回复 赞! 靠!

使用道具 举报

发表于 2019-3-29 15:03:53 | 显示全部楼层
这个真的厉害了.
回复 赞! 靠!

使用道具 举报

发表于 2019-9-25 09:26:05 | 显示全部楼层
真是厉害,膜拜了,新手学习
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-21 18:41 , Processed in 0.039478 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表