
;
; 3d Rotation, Coded by Ash [NLB]
; it's not TOO fast, but it's more understandable this way.
;

ideal						; ideal RULES
p386n						; 80386+
jumps						; jumps

segment code
assume cs:code,ds:code
org 100h

start:
		cli				; clear interrupts

                mov     ax,13h                  ; 320*200*256 Bios
                int     10h
                push    0a000h                  ; Dest. VgaSeg.
                pop     es

                mov     dx,3c8h                 ; dump palette
                lea     si,[palette]
                mov     cx,189*3
                xor     al,al
                out     dx,al
                inc     dx
                repz    outsb

mainloop:       inc     [xangle]                ; do the Angles
                and     [xangle],255
                inc     [yangle]
                and     [yangle],255
                inc     [zangle]
                and     [zangle],255

                mov     bp,[xangle]             ; get sin & cos values (x)
                movsx   bx,[sincos+bp]
                mov     [xsin],bx
                add     bp,64
                and     bp,255
                movsx   bx,[sincos+bp]
                mov     [xcos],bx

                mov     bp,[yangle]             ; get sin & cos values (y)
                movsx   bx,[sincos+bp]
                mov     [ysin],bx
                add     bp,64
                and     bp,255
                movsx   bx,[sincos+bp]
                mov     [ycos],bx

                mov     bp,[zangle]             ; get sin & cos values (z)
                movsx   bx,[sincos+bp]
                mov     [zsin],bx
                add     bp,64
                and     bp,255
                movsx   bx,[sincos+bp]
                mov     [zcos],bx

                xor     si,si
                mov     cx,allpoints
alldots:        push    cx
                mov     bx,[xcos]               ; yt=y*cos(x)-z*sin(x)
                movsx   ax,[points+si+1]
                imul    bx
                xchg    ax,bp
                mov     bx,[xsin]
                movsx   ax,[points+si+2]
                imul    bx
                sub     bp,ax
                mov     [yt],bp

                mov     bx,[xsin]               ; zt=y*sin(x)+z*cos(x)
                movsx   ax,[points+si+1]
                imul    bx
                xchg    ax,bp
                mov     bx,[xcos]
                movsx   ax,[points+si+2]
                imul    bx
                add     bp,ax
                mov     [zt],bp

                mov     ax,[yt]                 ; yt=y & zt=z
                sar     ax,7
                mov     [y],ax
                mov     ax,[zt]
                sar     ax,7
                mov     [z],ax

                mov     bx,[ycos]               ; xt=x*cos(y)-z*sin(y)
                movsx   ax,[points+si]
                imul    bx
                xchg    ax,bp
                mov     bx,[ysin]
                mov     ax,[z]
                imul    bx
                sub     bp,ax
                mov     [xt],bp

                mov     bx,[ysin]               ; zt=x*sin(y)+z*cos(y)
                movsx   ax,[points+si]
                imul    bx
                xchg    ax,bp
                mov     bx,[ycos]
                mov     ax,[z]
                imul    bx
                add     bp,ax
                mov     [zt],bp

                mov     ax,[xt]                 ; xt=x & zt=z
                sar     ax,7
                mov     [x],ax
                mov     ax,[zt]
                sar     ax,7
                mov     [z],ax

                mov     bx,[zcos]               ; xt=x*cos(z)-y*sin(z)
                mov     ax,[x]
                imul    bx
                xchg    ax,bp
                mov     bx,[zsin]
                mov     ax,[y]
                imul    bx
                sub     bp,ax
                mov     [xt],bp

                mov     bx,[zsin]               ; yt=x*sin(z)+y*cos(z)
                mov     ax,[x]
                imul    bx
                xchg    ax,bp
                mov     bx,[zcos]
                mov     ax,[y]
                imul    bx
                add     bp,ax
                mov     [yt],bp

                mov     ax,[xt]                 ; xt=x & zt=z
                sar     ax,7
                mov     [x],ax
                mov     ax,[yt]
                sar     ax,7
                mov     [y],ax

                mov     ax,200                  ; x*200\z+200 = x
                mov     bx,[x]
                imul    bx
                mov     bx,[z]
                add     bx,200
                idiv    bx
                add     ax,160
                xchg    ax,bp

                mov     ax,200                  ; y*200\z+200 = y
                mov     bx,[y]
                imul    bx
                mov     bx,[z]
                add     bx,200
                idiv    bx
                add     ax,100

                mov     bx,320                  ; (y*320)+x
                mul     bx
                add     ax,bp
                xchg    di,ax

                mov     ax,[z]                  ; get color of point from z
                add     ax,74

                mov     [byte ptr es:di],al     ; dump a dot
                mov     [deltable+si],di        ; save position for erase

                add     si,3
                pop     cx
                loop    alldots

                mov     dx,3dah                 ; vertical retrace
                in      al,dx
                test    al,8
                jne     $-3
                in      al,dx
                test    al,8
                je      $-3

                xor     si,si			; erase points
                mov     cx,allpoints
erasethem:      push    cx
                mov     di,[deltable+si]
                mov     [byte ptr es:di],0
                add     si,3
                pop     cx
                loop    erasethem

                in      al,60h                  ; scan keyboard
                cmp     al,1                    ; is escape pressed?
                jne     mainloop                ; if not, loop 3d

                mov     ax,3                    ; 80*25*16 Bios
                int     10h
                mov     ax,4c00h                ; go back to dos
                int     21h


        ;
        ; Data Starts here..
        ;


  label sincos byte
  db 0,3,6,9,12,16,19,22,25,28,31,34,37,40,43,46,49,51,54,57,60,63,65,68,71
  db 73,76,78,81,83,85,88,90,92,94,96,98,100,102,104,106,107,109,111,112,113
  db 115,116,117,118,120,121,122,122,123,124,125,125,126,126,126,127,127,127
  db 127,127,127,127,126,126,126,125,125,124,123,122,122,121,120,118,117,116
  db 115,113,112,111,109,107,106,104,102,100,98,96,94,92,90,88,85,83,81,78,76
  db 73,71,68,65,63,60,57,54,51,49,46,43,40,37,34,31,28,25,22,19,16,12,9,6,3,0
  db 253,250,247,244,240,237,234,231,228,225,222,219,216,213,210,207,205,202
  db 199,196,193,191,188,185,183,180,178,175,173,171,168,166,164,162,160,158
  db 156,154,152,150,149,147,145,144,143,141,140,139,138,136,135,134,134,133
  db 132,131,131,130,130,130,129,129,129,129,129,129,129,130,130,130,131,131
  db 132,133,134,134,135,136,138,139,140,141,143,144,145,147,149,150,152,154
  db 156,158,160,162,164,166,168,171,173,175,178,180,183,185,188,191,193,196
  db 199,202,205,207,210,213,216,219,222,225,228,231,234,237,240,244,247,250
  db 253

  label         points byte                     ; the points
                c = -35				; 4x*4y*4z (=64) points
                rept 4
                b = -35
                rept 4
                a = -35
                rept 4
                db a,b,c
                a = a + 20
                endm
                b = b + 20
                endm
                c = c + 20
                endm

  label         palette byte                    ; the palette
                db 0,0,0			; 63*2 greentint
                d = 63
                rept 63
                db 0,d,0,0,d,0
                d = d - 1
                endm

  allpoints     equ 64				; total points

  xangle        dw 0
  yangle        dw 0
  zangle        dw 0
  xsin          dw ?
  ysin          dw ?
  zsin          dw ?
  xcos          dw ?
  ycos          dw ?
  zcos          dw ?
  xt            dw ?
  yt            dw ?
  zt            dw ?
  x             dw ?
  y             dw ?
  z             dw ?
  deltable      dw allpoints dup (?)

ends code
end start

