Stack Segment Stack
dw 200 dup(?)
Stack Ends
Code Segment ; Code segment starts
Assume cs:code,ds:code ; Let cs and ds point to code segment
START: ; Main program
mov ax,0013h ; Init vga
int 10h
mov ax,cs
mov ds,ax ; ds points to codesegment
mov ax,0a000h
mov es,ax ; es points to vga
lea si,[Palette] ; Set palette
mov dx,3c8h
xor al,al
out dx,al
mov dx,3c9h
mov cx,189*3
tran:mov al,byte ptr [si]
out dx,al
inc si
loop tran
mov [DeltaX],1 ; Initial speed of rotation
mov [DeltaY],1 ; Change this and watch what
mov [DeltaZ],1 ; happens. It's fun!
mov [Xoff],256
mov [Yoff],256 ; Used for calculating vga-pos
mov [Zoff],300 ; Distance from viewer
MainLoop:
call MainProgram ; Yep... do it all... ;-)
in al,60h ; Scan keyboard
cmp al,1 ; Test on ESCAPE
jne MainLoop ; Continue if not keypressed
; === Quit to DOS ===
mov ax,0003h ; Back to textmode
int 10h
lea dx,[Credits]
mov ah,9
int 21h
mov ax,4c00h ; Return control to DOS
int 21h ; Call DOS interrupt
; === Sub-routines ===
WaitVrt PROC ; Waits for vertical retrace to reduce "snow"
mov dx,3dah
Vrt: in al,dx
test al,8
jnz Vrt ; Wait until Verticle Retrace starts
NoVrt:in al,dx
test al,8
jz NoVrt ; Wait until Verticle Retrace ends
ret ; Return to main program
WaitVrt ENDP
UpdateAngles PROC
; Calculates new x,y,z angles
; to rotate around
mov ax,[XAngle] ; Load current angles
mov bx,[YAngle]
mov cx,[ZAngle]
add ax,[DeltaX] ; Add velocity
and ax,11111111b ; Range from 0..255
mov [XAngle],ax ; Update X
add bx,[DeltaY] ; Add velocity
and bx,11111111b ; Range from 0..255
mov [YAngle],bx ; Update Y
add cx,[DeltaZ] ; Add velocity
and cx,11111111b ; Range from 0..255
mov [ZAngle],cx ; Update Z
ret
UpdateAngles ENDP
GetSinCos PROC
; Needed : bx=angle (0..255)
; Returns: ax=Sin bx=Cos
push bx ; Save angle (use as pointer)
shl bx,1 ; Grab a word so bx=bx*2
mov ax,[SinCos + bx] ; Get sine
pop bx ; Restore pointer into bx
push ax ; Save sine on stack
add bx,64 ; Add 64 to get cosine
and bx,11111111b ; Range from 0..255
shl bx,1 ; *2 coz it's a word
mov ax,[SinCos + bx] ; Get cosine
mov bx,ax ; Save it bx=Cos
pop ax ; Restore ax=Sin
ret
GetSinCos ENDP
SetRotation PROC
; Set sine & cosine of x,y,z
mov bx,[XAngle] ; Grab angle
call GetSinCos ; Get the sine&cosine
mov [Xsin],ax ; Save sin
mov [Xcos],bx ; Save cos
mov bx,[Yangle]
call GetSinCos
mov [Ysin],ax
mov [Ycos],bx
mov bx,[Zangle]
call GetSinCos
mov [Zsin],ax
mov [Zcos],bx
ret
SetRotation ENDP
RotatePoint PROC ; Rotates the point around x,y,z
; Gets original x,y,z values
; This can be done elsewhere
mov al,byte ptr [Cube+si] ; si = X (movsx coz of byte)
cbw
mov [X],ax
mov al,byte ptr [Cube+si+1] ; si+1 = Y
cbw
mov [Y],ax
mov al,byte ptr [Cube+si+2] ; si+2 = Z
cbw
mov [Z],ax
; Rotate around x-axis
; YT = Y * COS(xang) - Z * SIN(xang) / 256
; ZT = Y * SIN(xang) + Z * COS(xang) / 256
; Y = YT
; Z = ZT
mov ax,[Y]
cwd
mov bx,[XCos]
imul bx ; ax = Y * Cos(xang)
mov bp,ax
mov ax,[Z]
cwd
mov bx,[XSin]
imul bx ; ax = Z * Sin(xang)
sub bp,ax
mov ax,bp
cwd
mov bx,256 ; bp = Y * Cos(xang) - Z * Sin(xang)
idiv bx ; bp = Y * Cos(xang) - Z * Sin(xang) / 256
mov [Yt],ax
mov ax,[Y]
cwd
mov bx,[XSin]
imul bx ; ax = Y * Sin(xang)
mov bp,ax
mov ax,[Z]
cwd
mov bx,[XCos]
imul bx ; ax = Z * Cos(xang)
add bp,ax
mov ax,bp
cwd
mov bx,256 ; bp = Y * SIN(xang) + Z * COS(xang)
idiv bx ; bp = Y * SIN(xang) + Z * COS(xang) / 256
mov [Zt],ax
mov ax,[Yt] ; Switch values
mov [Y],ax
mov ax,[Zt]
mov [Z],ax
; Rotate around y-axis
; XT = X * COS(yang) - Z * SIN(yang) / 256
; ZT = X * SIN(yang) + Z * COS(yang) / 256
; X = XT
; Z = ZT
mov ax,[X]
cwd
mov bx,[YCos]
imul bx ; ax = X * Cos(yang)
mov bp,ax
mov ax,[Z]
cwd
mov bx,[YSin]
imul bx ; ax = Z * Sin(yang)
sub bp,ax
mov ax,bp
cwd
mov bx,256 ; bp = X * Cos(yang) - Z * Sin(yang)
idiv bx ; bp = X * Cos(yang) - Z * Sin(yang) / 256
mov [Xt],ax
mov ax,[X]
cwd
mov bx,[YSin]
imul bx ; ax = X * Sin(yang)
mov bp,ax
mov ax,[Z]
cwd
mov bx,[YCos]
imul bx ; ax = Z * Cos(yang)
add bp,ax
mov ax,bp
cwd
mov bx,256 ; bp = X * SIN(yang) + Z * COS(yang)
idiv bx ; bp = X * SIN(yang) + Z * COS(yang) / 256
mov [Zt],ax
mov ax,[Xt] ; Switch values
mov [X],ax
mov ax,[Zt]
mov [Z],ax
; Rotate around z-axis
; XT = X * COS(zang) - Y * SIN(zang) / 256
; YT = X * SIN(zang) + Y * COS(zang) / 256
; X = XT
; Y = YT
mov ax,[X]
cwd
mov bx,[ZCos]
imul bx ; ax = X * Cos(zang)
mov bp,ax
mov ax,[Y]
cwd
mov bx,[ZSin]
imul bx ; ax = Y * Sin(zang)
sub bp,ax
mov ax,bp
cwd
mov bx,256 ; bp = X * Cos(zang) - Y * Sin(zang)
idiv bx ; bp = X * Cos(zang) - Y * Sin(zang) / 256
mov [Xt],ax
mov ax,[X]
cwd
mov bx,[ZSin]
imul bx ; ax = X * Sin(zang)
mov bp,ax
mov ax,[Y]
cwd
mov bx,[ZCos]
imul bx ; ax = Y * Cos(zang)
add bp,ax
mov ax,bp
cwd
mov bp,256 ; bp = X * SIN(zang) + Y * COS(zang)
idiv bp ; bp = X * SIN(zang) + Y * COS(zang) / 256
mov [Yt],ax
mov ax,[Xt] ; Switch values
mov [X],ax
mov ax,[Yt]
mov [Y],ax
ret
RotatePoint ENDP
ShowPoint PROC
; Calculates screenposition and
; plots the point on the screen
mov ax,[Xoff] ; Xoff*X / Z+Zoff = screen x
cwd
mov bx,[X]
imul bx
mov bx,[Z]
add bx,[Zoff] ; Distance
idiv bx
add ax,[Mx] ; Center on screen
mov bp,ax
mov ax,[Yoff]
cwd ; Yoff*Y / Z+Zoff = screen y
mov bx,[Y]
imul bx
mov bx,[Z]
add bx,[Zoff] ; Distance
idiv bx
add ax,[My] ; Center on screen
mov bx,320
imul bx
add ax,bp ; ax = (y*320)+x
mov di,ax
mov ax,[Z] ; Get color from Z
add ax,50 ; (This piece of code could be improved)
mov byte ptr es:[di],al ; Place a dot with color al
mov [Erase+si],di ; Save position for erase
ret
ShowPoint ENDP
MainProgram PROC
call UpdateAngles ; Calculate new angles
call SetRotation ; Find sine & cosine of those angles
xor si,si ; First 3d-point
mov cx,MaxPoints
ShowLoop:
call RotatePoint ; Rotates the point using above formulas
call ShowPoint ; Shows the point
add si,3 ; Next 3d-point
loop ShowLoop
call WaitVrt ; Wait for retrace
xor si,si ; Starting with point 0
xor al,al ; Color = 0 = black
mov cx,MaxPoints
Deletion:
mov di,[Erase+si] ; di = vgapos old point
mov byte ptr es:[di],al ; Delete it
add si,3 ; Next point
loop Deletion
ret
MainProgram ENDP
; === DATA ===
Credits DB 13,10,"Code by Vulture / Outlaw Triad",13,10,"$"
SinCos Label Word ; 256 values
dw 0,6,13,19,25,31,38,44,50,56
dw 62,68,74,80,86,92,98,104,109,115
dw 121,126,132,137,142,147,152,157,162,167
dw 172,177,181,185,190,194,198,202,206,209
dw 213,216,220,223,226,229,231,234,237,239
dw 241,243,245,247,248,250,251,252,253,254
dw 255,255,256,256,256,256,256,255,255,254
dw 253,252,251,250,248,247,245,243,241,239
dw 237,234,231,229,226,223,220,216,213,209
dw 206,202,198,194,190,185,181,177,172,167
dw 162,157,152,147,142,137,132,126,121,115
dw 109,104,98,92,86,80,74,68,62,56
dw 50,44,38,31,25,19,13,6,0,-6
dw -13,-19,-25,-31,-38,-44,-50,-56,-62,-68
dw -74,-80,-86,-92,-98,-104,-109,-115,-121,-126
dw -132,-137,-142,-147,-152,-157,-162,-167,-172,-177
dw -181,-185,-190,-194,-198,-202,-206,-209,-213,-216
dw -220,-223,-226,-229,-231,-234,-237,-239,-241,-243
dw -245,-247,-248,-250,-251,-252,-253,-254,-255,-255
dw -256,-256,-256,-256,-256,-255,-255,-254,-253,-252
dw -251,-250,-248,-247,-245,-243,-241,-239,-237,-234
dw -231,-229,-226,-223,-220,-216,-213,-209,-206,-202
dw -198,-194,-190,-185,-181,-177,-172,-167,-162,-157
dw -152,-147,-142,-137,-132,-126,-121,-115,-109,-104
dw -98,-92,-86,-80,-74,-68,-62,-56,-50,-44
dw -38,-31,-25,-19,-13,-6
Cube Label Byte ; The 3d points
c = -35 ; 5x*5y*5z (=125) points
rept 5
b = -35
rept 5
a = -35
rept 5
db a,b,c
a = a + 20
endm
b = b + 20
endm
c = c + 20
endm
Palette Label Byte ; The palette to use
db 1,1,1 ; 63*3 gray-tint
d = 63
rept 63
db d,d,d
db d,d,d
db d,d,d
d = d - 1
endm
X DW ? ; X variable for formula
Y DW ?
Z DW ?
Xt DW ? ; Temporary variable for x
Yt DW ?
Zt DW ?
XAngle DW 0 ; Angle to rotate around x
YAngle DW 0
ZAngle DW 0
DeltaX DW ? ; Amound Xangle is increased each time
DeltaY DW ?
DeltaZ DW ?
Xoff DW ?
Yoff DW ?
Zoff DW ? ; Distance from viewer
XSin DW ? ; Sine and cosine of angle to rotate around
XCos DW ?
YSin DW ?
YCos DW ?
ZSin DW ?
ZCos DW ?
Mx DW 140 ; Middle of the screen
My DW 80
MaxPoints EQU 125 ; Number of 3d Points
Erase DW MaxPoints DUP (?) ; Array for deletion screenpoints
code ENDS ; End of codesegment
END START ; The definite end.... :)
- [mx10209] 看后很受启发,我们一定要培养独立思考的能力,向博主学习! 12/24 12:49
- [gao2951713] 虽然参加工作了,但是我一直想搞懂汇编,想享受那种操控机器的快感。所以又重新回到汇编的怀抱里来了。 12/04 17:15
- [tomato] 王爽老师《汇编语言》上都是博主写的这样。楼上是没看这本书喽!强烈建议楼上学习这本书! 书写格式应该 11/25 19:19
- [diabloduke] assume cs:code code segment 请教一下,为什么这段代码 11/25 08:43
- [wswcsxp2008] 再次支持一下楼上所言,时间真是个好东西。我怎么会总觉得时间过的太快,但早上总不能早起呢,唉,现在凌晨 10/06 00:53
- [wangcz] 我也是刚开始学习汇编,有时候又没有时间看课本,现在才知道时间是多么宝贵。看了之后很受启发,脚踏实地才 05/09 15:36
- [fanqingtulv] 谢谢,学到了好多的东西。。 11/27 18:26
- [18757223] 好帖 10/20 17:10
- [游客] 三过家门而不入 是忘记了带钥匙! --润丰彩票 10/12 23:12
- [游客] 我学的是pascal 07/26 16:23
- [wuyoudaozhu] 你好,谢谢您的检查。现在我有个困惑:在执行jmp ax命令时,IP是先变为0,然后IP再等于[ax] 10/24 10:27
- [nice_future] 谢谢您的评论,我会继续努力!我起初是想学点技术的,学着学着感觉学汇编成为兴趣啦! 08/17 07:36
- [hwenycocodq520] 老师问你个问题: 物理地址为21F60H,偏移地址为:FFFFH 求段地址为多少: 我解 05/19 17:24
- [fxl] 谢谢 12/28 14:26
- [nono] 谢谢博主对我作业的检查。 以后请多多指教 11/05 17:44
- [891204dh] 呵呵 老哥 不错哟,大家都来谢你了呢 所以 我也来了 嘻嘻 08/26 01:26
- [semidotnet] 来这里转转,谢谢你对我作业的点评。 08/18 10:43
- [fang] 如果只知道8KB怎么计算 13根地址线的寻址能力是怎么计算机出来的 ? 07/12 23:39
- [zdpopup] 谢谢你的 鼓励.我会的 07/01 00:55
- [squaaa] mess 谢谢你对我前两次作业的检查! 我会继续加油。 01/17 14:43