;
;  Line-Vector-routine v2.2
;
;  done 1995 by Capella/Escape
;  this routine is only for Escape-usage .... DON'T SPREAD!!!!
;

ideal
model large
p386n
stack 256

assume cs:coding

points = 18+48             ; Anzahl Punkte
areas = 18+48            ; Anzahl Linien

;-------------------------------------
macro  setcol   backcol

       mov dx,03c8h
       xor al,al
       out dx,al
       inc dx
       mov al,backcol
       out dx,al
       out dx,al
       out dx,al

endm
;-------------------------------
macro  setpage newpage

       mov dx,03d4h
       mov ax,newpage
       out dx,ax

endm
;-------------------------------

segment  coding

start:     mov ax,data1
           mov ds,ax
           assume ds:data1

           mov ax,0a000h
           mov es,ax
           assume es:0a000h

           call set320400

           mov ax,0a800h
           mov es,ax
           assume es:0a800h
           
main:      call  rotate_x       
           call  rotate_y
           call  rotate_z
           
           call transform
           
           mov [ds:color],1         ; Objekt auf Seite 2 darstellen
           mov di,offset _2dpoints
           call draw_obj
           
           setpage 800ch           ; Seite 2 an
           
           mov dx,03dah
wb1:       in al,dx
           test al,8
           jne wb1
wb2:       in al,dx
           test al,8
           je wb2

           mov ax,0a000h
           mov es,ax
           assume es:0a000h
           
           mov [ds:color],0        ; Objekt auf Seite 1 l敗chen
           mov di,offset old2d    
           call draw_obj
           
           call get_oldpos         ; Positionen von Seite 2 retten
           
          ; add [ds:xw],2
          ; add [ds:yw],2
          ; add [ds:zw],2
           
           call rotate_x        
           call rotate_y
           call rotate_z
           
           call transform
           
           mov [ds:color],1        ; Objekt auf Seite 1 darstellen
           mov di,offset _2dpoints
           call draw_obj
           
           setpage 000ch           ; Seite 1 an
       
           mov dx,03dah
wb3:       in al,dx
           test al,8
           jne wb3
wb4:       in al,dx
           test al,8
           je wb4

           mov ax,0a800h
           mov es,ax
           assume es:0a800h
           
           mov [ds:color],0        ; Seite 2 l敗chen
           mov di,offset old2d
           call draw_obj
           call get_oldpos         ; Positionen von Seite 1 retten
           
           add [ds:xw],2        ; Neue Winkel berechnen
           add [ds:yw],4
           add [ds:zw],2
           
warte:     in al,60h            ; Auf 'ESCAPE'-Taste warten
           cmp al,01
           jne main

           
exit:      mov ax,0003h
           int 10h
           mov ax,4c00h
           int 21h

;ｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱ
; ROTATIONS-ROUTINE / dreht die 3d-koordinaten in x,y und z-richtung
;ｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱ

proc  rotate_x    NEAR
     
     mov   si,offset xpos
     mov   di,offset _3dpoints
     mov   cx,points

rotx_it:
     push  cx
     
     mov   ax,[ds:zw]       
     call  cosinus
     imul  [word ds:si]
     mov   cx,dx
     mov   ax,[ds:zw] 
     call  sinus
     imul  [word ds:si+2*points]
     sub   dx,cx
     sal   dx,1
     sal   dx,1
     mov   [ds:di],dx  

     mov   ax,[ds:zw]       
     call  sinus
     imul  [word ds:si]
     mov   cx,dx
     mov   ax,[ds:zw] 
     call  cosinus
     imul  [word ds:si+2*points]
     add   dx,cx
     sal   dx,1
     sal   dx,1
     mov   [ds:di+2*points],dx                
      
     pop cx
     add si,2
     add di,2
     dec cx
     jnz rotx_it
     ret

endp  rotate_x

proc  rotate_y    NEAR

     mov cx,points
     mov si,offset xpos
     mov di,offset _3dpoints

roty_it:     
     push cx

     mov   ax,[ds:yw]       
     call  cosinus
     imul  [word ds:si]
     mov   cx,dx
     mov   ax,[ds:yw] 
     call  sinus
     imul  [word ds:si+4*points]
     sub   dx,cx
     sal   dx,1
     sal   dx,1
     mov   [ds:di],dx  

     mov   ax,[ds:yw]       
     call  sinus
     imul  [word ds:si]
     mov   cx,dx
     mov   ax,[ds:yw] 
     call  cosinus
     imul  [word ds:si+4*points]
     add   dx,cx
     sal   dx,1
     sal   dx,1
     mov   [ds:di+4*points],dx                
      
     pop cx
     add si,2
     add di,2
     dec cx
     jnz roty_it
     ret

endp  rotate_y

proc  rotate_z    NEAR

     mov cx,points
     mov si,offset xpos
     mov di,offset _3dpoints

rotz_it:
     
     push cx

     mov   ax,[ds:xw]       
     call  cosinus
     imul  [word ds:si+2*points]
     mov   cx,dx
     mov   ax,[ds:xw] 
     call  sinus
     imul  [word ds:di+4*points]
     sub   dx,cx
     sal   dx,1
     sal   dx,1
     mov   [ds:di+2*points],dx  

     mov   ax,[ds:xw]       
     call  sinus
     imul  [word ds:si+2*points]
     mov   cx,dx
     mov   ax,[ds:xw] 
     call  cosinus
     imul  [word ds:di+4*points]
     add   dx,cx
     sal   dx,1
     sal   dx,1
     mov   [ds:di+4*points],dx                
     
     pop   cx
     add si,2
     add di,2
     dec cx
     jnz rotz_it
     ret

endp  rotate_z

;ｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱ
; DRAW-OBJECT / zeichnet das object bestehend aus den 2d-koordinaten
;ｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱ

proc  draw_obj    NEAR
     
     mov   si,offset lines
     mov   cx,areas

Draw_Bonds:
     
     push  cx
     xor   bh,bh
     mov   bl,[ds:si]    
     shl   bl,1
     mov   ax,[ds:di+bx]        
     mov   cx,[ds:di+2*points+bx] 
     mov   [ds:x1],ax
     mov   [ds:y1],cx
     inc   si
     mov   bl,[ds:si]
     shl   bl,1
     mov   ax,[ds:di+bx]        
     mov   cx,[ds:di+2*points+bx]  
     mov   [ds:x2],ax
     mov   [ds:y2],cx
     push  si
     push  di
     call  drawline
     pop   di
     pop   si
     inc   si
     pop   cx
     dec cx
     jnz  Draw_Bonds
     ret

endp  draw_obj 

;ｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱ
; TRANSFORMATION-ROUTINE / rechnet die 3d-koord. in 2d koord. um
;ｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱ

proc  transform     NEAR
     
         mov   cx,points
         mov   di,offset _2dpoints
         mov   si,offset _3dpoints

trans_it:mov   bx,[ds:si+4*points] 
         sub   bx,[ds:dist]
     
         mov   ax,[ds:dist]
         imul  [word ds:si]
         idiv  bx            
         sar   ax,1
         sar   ax,1
         sar   ax,1
         sar   ax,1
         add   ax,[ds:x_add]
         mov   [ds:di],ax      
     
         mov   ax,[ds:dist]
         imul  [word ds:si+2*points]
         idiv  bx
         sar   ax,1
         sar   ax,1
         sar   ax,1
         sar   ax,1
         add   ax,[ds:y_add]
         mov   [ds:di+2*points],ax 
     
         add si,2
         add di,2
         dec cx
         jnz trans_it
         ret

endp  transform 

;ｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱ
; COSINUS-ROUTINE
;ｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱ

proc  cosinus     NEAR

     add   ax,64

     push  bx
     push  cx
     push  si
     
     mov   bx,ax
     shl   ax,1
     and   ax,0ffh       
     mov   si,offset sinustable
     add   si,ax
     mov   ax,[ds:si]     
     clc
     shl   bl,1         
     jae   cos_pos
     neg   ax            
cos_pos:
     pop   si
     pop   cx
     pop   bx
     ret

endp  cosinus

;ｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱ
; SINUS-ROUTINE
;ｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱ

proc  sinus    NEAR

     push  bx
     push  cx
     push  si
     
     mov   bx,ax
     shl   ax,1
     and   ax,0ffh       
     mov   si,offset sinustable
     add   si,ax
     mov   ax,[ds:si]     
     clc
     shl   bl,1         
     jae   sin_pos
     neg   ax            
sin_pos:
     pop   si
     pop   cx
     pop   bx
     ret

endp  sinus

;ｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱ
; DRAWLINE-ROUTINE / zieht eine linie von x1,y1 nach x2,y2 mit farbe col
;ｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱｱ

proc  drawline   NEAR
     
     mov   ax,[ds:x1]
     cmp   ax,[ds:x2]
     jz    no_xadd
     jmp   draw_it

no_xadd:
     
     mov   ax,[ds:y1]
     cmp   ax,[ds:y2]
     jnz   draw_it
     
     mov ax,[ds:x1]
     mov bx,[ds:y1]
     jmp   stop_line

draw_it:
     
     push  bp
     mov   ax,[ds:x1]
     mov   bx,[ds:y1]
     push  ax
     push  bx
     mov   bx,4340h
     mov   cx,[ds:x2]
     sub   cx,ax
     jge   deltax_1
     mov   bl,48h
     neg   cx

deltax_1:
     
     mov   dx,[ds:y2]
     pop   si
     push  si
     sub   dx,si
     jge   deltay_1
     mov   bh,4bh
     neg   dx

deltay_1:

     mov   si,offset line_add
     mov   [word cs:si],bx
     cmp   cx,dx
     jge   deltax_2
     mov   bl,90h
     xchg  cx,dx
     jmp   achse3

deltax_2:
     
     mov   bh,90h

achse3:
     
     mov   si,offset line_sub
     mov   [word cs:si],bx
     shl   dx,1
     mov   bp,dx
     sub   dx,cx
     mov   di,dx
     sub   dx,cx
     pop   bx
     pop   ax

line_loop:
     
     push  di
     push  ax
     push  dx
     push  bx
     push  cx
     
     push ax
     mov ax,80
     imul bx
     pop cx
     mov bx,cx
     shr bx,1
     shr bx,1
     add ax,bx
     mov si,ax

     and cl,3
     mov ah,1
     shl ah,cl
     mov dx,03c4h
     mov al,02h
     out dx,ax

     mov al,[ds:color]
     mov [es:si],al
     
     pop   cx
     pop   bx
     pop   dx
     pop   ax
     pop   di
     cmp   di,0
     jge   line_add

line_sub:
     
     inc   ax
     inc   bx
     add   di,bp
     loop  line_loop
     jmp   end_line

line_add:
     
     inc   ax
     inc   bx
     add   di,dx
     loop  line_loop

end_line:
     
     pop     bp

stop_line:
     
     ret

endp  drawline 



proc  get_oldpos  NEAR

         mov cx,2*points

         mov si,offset _2dpoints
         mov di,offset old2d

old_loop:mov ax,[ds:si]
         mov [ds:di],ax
         add si,2
         add di,2
         dec cx
         jnz old_loop
         
         ret

endp  get_oldpos


;ｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰ
; SET 320*400 Graphics-mode (based on 4 bitplane-splitting) 
;ｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰ

proc  set320400  NEAR

              mov ax,0013h      
              int 10h

              mov dx,03c4h
              mov al,04h
              out dx,al
              inc dx
              in al,dx
              and al,11110111b
              out dx,al
              dec dx
              
              mov ax,0f02h
              out dx,ax

              mov dx,03d4h
              mov al,14h
              out dx,al
              inc dx
              in al,dx
              and al,10111111b
              out dx,al
              dec dx
              mov al,17h
              out dx,al
              inc dx
              in al,dx
              or al,01000000b
              out dx,al

              mov dx,03d4h
              mov al,09h
              out dx,al
              inc dx
              in al,dx
              and al,01110000b
              out dx,al
              
              mov dx,03c4h
              mov ax,0f02h
              out dx,ax

              mov ax,0a000h
              mov es,ax
              assume es:0a000h
              
              mov cx,64000      ; alle bitplanes auf beiden grafikseiten
              xor di,di         ; l敗chen...
              xor eax,eax
              cld
              rep stosd

              ret

endp  set320400


ends  coding

segment  data1

;
; OBJEKT DATEN
;

xpos  dw -400,-100,-300,-100,-300,-100,-400,-100 ;C
      dw -800,-500,-700,-500,-700,-500,-800,-600,-800,-600,-800,-500 ;S
      dw -1200,-900,-1100,-900,-1100,-1000,-1100,-1000,-1100,-900,-1200,-900 ;E

      dw 100,400,200,300,200,300,200,300,100,200,300,400 ; A
      dw 500,800,600,700,600,700,600,800,500,600 ;P
      dw 900,1200,1000,1200,1000,1100,1000,1100,1000,1200,900,1200 ;E

ypos  dw -350,-350,-200,-200,200,200,350,350     ;C
      dw -350,-350,-200,-200,-100,-100,100,100,200,200,350,350 ;S
      dw -350,-350,-200,-200,-100,-100,100,100,200,200,350,350 ;E

      dw -350,-350,-200,-200,-100,-100,100,100,350,350,350,350 ;A
      dw -350,-350,-200,-200,-100,-100,100,100,350,350 ;P
      dw -350,-350,-200,-200,-100,-100,100,100,200,200,350,350 ;E

zpos  dw 300,300,300,300,300,300,300,300         ;C
      dw 300,300,300,300,300,300,300,300,300,300,300,300 ;S
      dw 300,300,300,300,300,300,300,300,300,300,300,300 ;E

      dw 300,300,300,300,300,300,300,300,300,300,300,300 ;A
      dw 300,300,300,300,300,300,300,300,300,300 ;P
      dw 300,300,300,300,300,300,300,300,300,300,300,300 ;E

;
; BINDUNGSLISTE F啌 DIE OBJEKT-PUNKTE
;

lines db 0,1         ;C
      db 2,3
      db 4,5
      db 6,7
      
      db 0,6
      db 1,3
      db 2,4
      db 5,7

      db 8,9         ;S
      db 10,11
      db 12,13
      db 14,15
      db 16,17
      db 18,19

      db 8,14
      db 9,11
      db 10,12
      db 13,19
      db 15,17
      db 16,18

      db 20,21   ;E
      db 22,23
      db 24,25
      db 26,27
      db 28,29
      db 30,31

      db 20,30
      db 21,23
      db 22,24
      db 25,27
      db 26,28
      db 29,31

      db 32,33  ;A
      db 34,35
      db 36,37
      db 38,39
      db 40,41
      db 42,43

      db 32,40
      db 33,43
      db 34,36
      db 35,37
      db 38,41
      db 39,42

      db 44,45  ;P
      db 46,47
      db 48,49
      db 50,51
      db 52,53

      db 44,52
      db 45,51
      db 46,48
      db 47,49
      db 50,53

      db 54,55  ;E
      db 56,57
      db 58,59
      db 60,61
      db 62,63
      db 64,65

      db 54,64
      db 55,57
      db 56,58
      db 59,61
      db 60,62
      db 63,65



;
; DISTANZ VOM AUGE DES BETRACHTERS IN DEN 3D-RAUM
;

dist  dw 2000

;
; SINUSTABELLE MIT 128 WERTEN
;

sinustable dw 0000h,0192h,0324h,04b5h,0646h
           dw 07d6h,0964h,0af1h,0c7ch,0e06h,0f8dh
           dw 1112h,1294h,1413h,1590h,1709h,187eh
           dw 19efh,1b5dh,1cc6h,1e2bh,1f8ch,20e7h
           dw 223dh,238eh,24dah,2620h,2760h,289ah
           dw 29ceh,2afbh,2c21h,2d41h,2e5ah,2f6ch
           dw 3076h,3179h,3274h,3368h,3453h,3537h
           dw 3612h,36e5h,37b0h,3871h,392bh,39dbh
           dw 3a82h,3b21h,3bb6h,3c42h,3cc5h,3d3fh
           dw 3dafh,3e15h,3e72h,3ec5h,3f0fh,3f4fh
           dw 3f85h,3fb1h,3fd4h,3fech,3ffbh,4000h
           dw 3ffbh,3fech,3fd4h,3fb1h,3f85h,3f4fh
           dw 3f0fh,3ec5h,3e72h,3e15h,3dafh,3d3fh
           dw 3cc5h,3c42h,3bb6h,3b21h,3a82h,39dbh
           dw 392bh,3871h,37b0h,36e5h,3612h,3537h
           dw 3453h,3368h,3274h,3179h,3076h,2f6ch
           dw 2e5ah,2d41h,2c21h,2afbh,29ceh,289ah
           dw 2760h,2620h,24dah,238eh,223dh,20e7h
           dw 1f8ch,1e2bh,1cc6h,1b5dh,19efh,187eh
           dw 1709h,1590h,1413h,1294h,1112h,0f8dh
           dw 0e06h,0c7ch,0af1h,0964h,07d6h,0646h
           dw 04b5h,0324h,0192h
  
;
; LINIEN-PUNKTE F啌 draw_obj-ROUTINE
;

x1      dw 0
x2      dw 0
y1      dw 0
y2      dw 0

;
; WINKEL F啌 DIE DREHUNGEN IN X,Y UND Z-RICHTUNG
;

xw      dw 0     
yw      dw 0
zw      dw 0

        db "ESCAPE"

;
; PUFFER F啌 ROTIERTE 3D-KOORDINATEN
;

_3dpoints    dw 3*points DUP (1) ; gedrehte Koord.

;
; PUFFER F啌 UMGERECHNETE 2D-KOORDINATEN
;

_2dpoints   dw 2*points DUP (1) ; 2D-Koordinaten
     
;
; PUFFER F啌 ALTE 2D-KOORDINATEN
;

old2d       dw 2*points dup (0) ; Alte 2D-Koordinaten

;
; 2D-POINTER F啌 POSITIONIERUNG AUF BILDSCHIRM
;

x_add    dw 160
y_add    dw 200

color    db 1

ends  data1

end start
