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:
  transform_point
  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


