0xAA55 发表于 2014-1-31 23:14:24

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



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

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

xor ax,ax                                ;改写中断向量表
mov ds,ax
cli
mov word,TimerINT        ;新的时钟中断
mov ,cs
sti
mov ax,cs
mov ds,ax

mov ax,0xA000                        ;显存
mov es,ax

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

;取得时间
mov al,0x06                                ;中断计时器值以便于读取
out 0x43,al
in al,0x40                                ;读取计时器低位
mov ah,al
in al,0x40                                ;读取计时器高位
xchg ah,al                                ;交换高低位
not ax                                        ;得到计时器时钟数
mov ,ax
fild qword                ;读时钟计数
fcom qword        ;比较旧的时间值
fstsw ax
fwait
sahf
ja .TimeOK                                ;当新取得的时钟计数比旧的低时,更正时钟计数
inc dword
fst st0
fild qword                ;重新加载正确的时间
fwait
.TimeOK:
fst qword                ;将已经算出的时间存储起来,用于下一轮比较
fmul qword                ;转动速度
fdiv qword        ;晶振频率
;得到角度

fld st0                                        ;复制“角度”
fcos                                        ;求“角度”余弦
fst qword        ;一个存到矩阵的X_X
fstp qword        ;一个存到矩阵的Y_Y
fsin                                        ;求“角度”正弦
fst qword        ;存到矩阵的X_Y
fchs                                        ;求反
fstp qword        ;存到矩阵的Y_X

fild dword
fchs                                        ;Y
mov cx,SCRHEIGHT
xor di,di
.VLoop:
        fwait                                ;等FPU处理好
        fld1
        fadd                                ;Y+=1.0;
        fild dword
        fchs                                ;X
        push cx
        mov cx,SCRWIDTH
        .HLoop:
                fld1
                fadd                        ;X+=1.0;
                fld st1
                fmul qword
                fld st1
                fmul qword
                fadd
                fabs                        ;NewX=(X*m11+Y*m12)
                fistp dword
               
                fld st1
                fmul qword
                fld st1
                fmul qword
                fadd
                fabs                        ;NewY=(X*m21+Y*m22)
                fistp dword

                fwait                        ;等FPU处理好

                xor al,al
                cmp dword,DIAMONDSIZE
                ja .OutOfStupidDiamond
                cmp dword,DIAMONDSIZE
                ja .OutOfStupidDiamond
                mov al,
                add al,        ;AL为颜色值,设置AL为调色板颜色
                .OutOfStupidDiamond:
                stosb                        ;输出一个像素
        loop .HLoop
        pop cx
        fstp st0                        ;保护浮点堆栈
loop .VLoop
fstp st0                                ;保护浮点堆栈
jmp Show

NewX dd 0
NewY dd 0
C_HALFSCRWIDTH dd SCRWIDTH/2
C_HALFSCRHEIGHT dd SCRHEIGHT/2
C_SPEED dq TURNSPEED

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

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

CrystalFreq dq 1193.182

TimerINT:
inc dword
iret完整源码和编译器,回复后可见。**** Hidden Message *****

我有个梦 发表于 2014-3-26 16:35:54

lz好厉害

0xAA55 发表于 2015-9-18 21:40:58

已更新,提升了计时器精度。

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

langzhe 发表于 2017-11-12 20:57:16

666666666666

bigwind 发表于 2017-11-15 20:39:57

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

137734949 发表于 2018-1-25 10:53:59

   :):):)

夜凌夕殇 发表于 2018-1-27 09:13:45

厉害                              

watermelon 发表于 2018-9-8 11:02:51

哇好厉害,还是有好多指令不认识,好在有注释

FFFFFFFE 发表于 2019-3-29 15:03:53

这个真的厉害了.

村中一霸 发表于 2019-9-25 09:26:05

:lol 真是厉害,膜拜了,新手学习
页: [1]
查看完整版本: 【DOS】16位汇编实现DOS下256色图形文本模式旋转的菱形的表示