org 100h
section .text
%macro init_gfx 0
mov ax,0x13
int 0x10
%endmacro
%macro usleep 2 ; usecs hi, lo
mov ax,0x8600
mov cx, %1
mov dx, %2
int 0x15
%endmacro
%macro create_texture 0
mov di,texture
mov dx,4
mov bx,80
mov cx,20
mov ax,1
%%again:
rep stosb
mov cx,ax
mov ax,1
sub ax,cx
mov cx,20
dec bx
jnz %%again
mov cx,ax
mov ax,1
sub ax,cx
mov bx,80
mov cx,20
dec dx
jnz %%again
%endmacro
%macro blit 5 ; src, x,y, w,h
mov ax,0xA000
mov es,ax
mov si,%1
mov di,%2+320*%3
mov bx,%4
mov cx,%5
%%again:
rep movsb
add di,320-%4
mov cx,%4
dec bx
jnz %%again
%endmacro
%macro cls 0
; xor di,di
mov di,offscreen
mov al,50 ; 200
cl1:
mov dx,0x3c8
out dx,al ; 0x3c8 ;al
inc dx
; mov ah,al
; shr al,2
out dx,al ; 0x3c8 ;al
out dx,al ; 0x3c8 ;al
out dx,al ; 0x3c8 ;al
mov cx,320*4 ; *200
; mov al,ah
rep stosb
dec al
jnz cl1
%endmacro
%macro puts 1 ; str
mov dx,%1
mov ah,0x09
int 0x21
%endmacro
%macro exit 0
int 0x20
%endmacro
%macro angle_setup 0
fild word [angle]
fild word [Rads]
fdivp ; deg2rad
fsincos ; sin(a) and cos(a)
fild word [Scale]
fmulp
fstp dword [sine]
fild word [Scale]
fmulp
fstp dword [cosine]
%endmacro
%macro transform_point 0
; d - dist of screen from COP
; x / z = sx / d
; d * (x/z) = screen-x
mov ax,[pntY]
sub ax,[Size]
imul word [sine]
mov bx,dx
mov ax,[pntX]
sub ax,[Size]
imul word [cosine]
sub dx,bx
mov word [tmp1d],dx ; x
mov ax,[pntX]
sub ax,[Size]
imul word [sine]
mov bx,dx
mov ax,[pntY]
sub ax,[Size]
imul word [cosine]
add dx,bx
mov word [tmp2d],dx ; y
mov ax,[pntZ]
sub ax,[Size]
imul word [sine]
mov bx,dx
mov ax,[tmp2d]
imul word [cosine]
sub dx,bx
mov cx,dx ; z
add cx,180
mov ax,[tmp2d]
imul word [sine]
mov bx,dx
mov ax,[pntZ]
sub ax,[Size]
imul word [cosine]
add dx,bx
mov word [tmp4d],dx ; y
mov ax,[tmp1d] ; x
mov dx,150 ; 45
imul dx
idiv cx
add ax,160
add ax,offscreen
mov di,ax
mov ax,[tmp4d] ; [tmp2d] ; y
mov dx,150 ; 45
imul dx
idiv cx
add ax,100
; lea eax,[eax*4+eax]
; shl ax,6
mov dx,320
imul dx
add di,ax
; draw
shr cl,1
sub cl,65 ; 130
mov al,cl
; mov ax,1
cmp al,[di]
jge over_pixel
stosb
over_pixel:
;stosb
;add di,318
;stosb
;stosb
%endmacro
start:
; program code
init_gfx
; create_texture
; blit texture, 100, 100, 80, 80
; usleep 0x1,0xFFFF
; cls
; exit
; I think ss might already be same as ds
push ds
pop ss
;mov ax,0xA000
;mov es,ax
; loop for different angles
loop1:
push ds
pop es
cls
angle_setup
mov word [pntZ],80
moreZ:
mov word [pntY],80
moreY:
mov word [pntX],80
moreX:
cmp word [pntZ],80
je do
cmp word [pntZ],1
je do
cmp word [pntY],80
je do
cmp word [pntY],1
je do
cmp word [pntX],80
je do
cmp word [pntX],1
je do
jmp dont
do:
transform_point
dont:
dec word [pntX]
jnz moreX
dec word [pntY]
jnz moreY
dec word [pntZ]
jnz moreZ
; wait for vertical retrace
; mov dx,0x3da
; in al,dx
; and al,8
; jnz loop1 ; wait_retrace1
; copy offscreen to screen
mov ax,0xA000
mov es,ax
mov si,offscreen
mov cx,320*200
xor di,di
rep movsb
dec word [angle]
jnz loop1
exit
project_worker:
mov dx,150 ; 45
imul dx
idiv cx
;add ax,100
ret
rot_worker:
fld dword [sine]
; cos,y, x, x, y
fmulp
; y*cos, x, x, y
fld dword [cosine]
; sin, y*cos, x, x, y
fmulp st2
ret
rotate:
; mov bp,sp
;fldz
fst st3
call rot_worker
; ; y, x, x, y
; fld dword [sine]
; ; cos,y, x, x, y
; fmulp
; ; y*cos, x, x, y
; fld dword [cosine]
; ; sin, y*cos, x, x, y
; fmulp st2
; ; y*cos, x*sin, x, y
fsubp
; y*cos - x*sin, x, y
fstp st3
call rot_worker
; ; x, y, y*cos - x*sin
; fld dword [sine]
; ; cos, x, y, y*cos - x*sin
; fmulp
; ; x*cos, y, y*cos - x*sin
; fld dword [cosine]
; ; sin, x*cos, y, y*cos - x*sin
; fmulp st2
; ; x*cos, y*sin, y*cos - x*sin
faddp
; x*cos + y*sin, y*cos - x*sin
; 1) sine * [bp+4] - cosine * [bp+2]
; 0) sine * [bp+2] + cosine * [bp+4]
retn ; 4
section .data
;Hello db 'Hello world', 0xD, 0xA, '$'
angle dw 360
Rads dw 58
; Dist dw 45
Size dw 40
Scale dw 65535
; Points dw -50,-50,-50, -50,50,-50, -50,50,50, -50,-50,50
; Points2 dw 50,-50,-50, 50,50,-50, 50,50,50, 50,-50,50
section .bss
; uninitialized data
pntX: resw 1
pntY: resw 1
pntZ: resw 1
tmp1w: resw 1
tmp2w: resw 1
tmp0d: resd 1
tmp1d: resd 1
tmp2d: resd 1
tmp3d: resd 1
tmp4d: resd 1
sine: resd 1
cosine: resd 1
; texture: resb 6400 ; 80x80
offscreen: resb 64000