; ****************************************************************************
; sncomni.s (TRDOS 386, TRDOS v2.0 - sample binary file, 'sncomni.prg')
; ----------------------------------------------------------------------------
; SNCOMNI.PRG ! TEST program !  TRDOS 386 VGA Functionality test !
;
; 02/09/2016
;
; [ Last Modification: 10/02/2017 ]
;
; Derived from source code of 'OMNISCENT.ASM' by Dirk Kόppers
;          SNC_OMNI.COM	 (MSDOS) intro file, 1997
;
; Assembler: NASM 2.11

; (Original TASM -msdos- code has been modifed for TRDOS 386 system calls and
; other protected mode (TRDOS 386) interrupts.)
; ****************************************************************************

;		   ----====> Omniscent <====----
;
;   Omniscent was done by Pinker of SANCTION for the Mekka '97. The song
;   was written by Nyphton. It place XXX out of XXX.
;
;   Special thanks in alphabetical order :
;
;       Andreas Mautsch     (beta testing)
;       Axel Scheel Meyer   (MACM sources, nice IRC chat's)
;       Christian Cohnen    (for his help on perspective texture mapping and
;	   		designing world and script)
;       Daniel Weinand	    (song)
;       Funk                (for give me the idea trying a 4K Descent)
;       Stephanie Schepers  (moral and food support ;-) )
;
;       and all other SANCTION dudes for supporting this product !

; 16/10/2016
; 29/04/2016
; TRDOS 386 system calls (temporary list!)
_ver 	equ 0
_exit 	equ 1
_fork 	equ 2
_read 	equ 3
_write	equ 4
_open	equ 5
_close 	equ 6
_wait 	equ 7
_creat 	equ 8
_link 	equ 9
_unlink	equ 10
_exec	equ 11
_chdir	equ 12
_time 	equ 13
_mkdir 	equ 14
_chmod	equ 15
_chown	equ 16
_break	equ 17
_stat	equ 18
_seek	equ 19
_tell 	equ 20
_mount	equ 21
_umount	equ 22
_setuid	equ 23
_getuid	equ 24
_stime	equ 25
_quit	equ 26	
_intr	equ 27
_fstat	equ 28
_emt 	equ 29
_mdate 	equ 30
_video 	equ 31
_audio	equ 32
_timer	equ 33
_sleep	equ 34
_msg    equ 35
_geterr	equ 36
_rsvd1	equ 37
_pri	equ 38
_rele	equ 39
_fff	equ 40
_fnf	equ 41

%macro sys 1-4
    ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)	
    ; 03/09/2015	
    ; 13/04/2015
    ; Retro UNIX 386 v1 system call.	
    %if %0 >= 2   
        mov ebx, %2
        %if %0 >= 3    
            mov ecx, %3
            %if %0 = 4
               mov edx, %4   
            %endif
        %endif
    %endif
    mov eax, %1
    ;int 30h
    int 40h ; TRDOS 386 (TRDOS v2.0)	   
%endmacro

; TRDOS 386 (and Retro UNIX 386 v1) system call format:
; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>

; SNCOMNI.ASM
; ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
; Ί	This file is generated by The Interactive Disassembler (IDA)	    Ί
; Ί	Copyright (c) 2010 by Hex-Rays SA, <support@hex-rays.com>	    Ί
; Ί			 Licensed to: Freeware version			    Ί
; ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
;
; Input	MD5   :	933E2716A5E585459024215F4468CDBC

; File Name   :	C:\dosprogs\MEMDUMP.COM ; SNC_OMNI.COM UNPACKED!
; Format      :	MS-DOS COM-file
; Base Address:	0h Range: 100h-60100h Loaded length: 60000h

; NASM version: Erdogan Tan, 14/08/2016 (Modified from MEMDUMP.ASM)
; (SNC_OMNI.COM -> unpacking by using DosBox Debug -> MEMDUMP.COM ->
; disassembling by using IDA Pro Free -> MEMDUMP.ASM -> converting to
; NASM syntax (manual) -> test with DosBox -> correcting different code by
; matching MEMDUMP.LST and SNCOMNI.LST files -> this file !!!)

;==============================================================================
;		   constants
;==============================================================================

GMPort		equ 0331h
CMD_NOTEON      equ 090h
CMD_NOTEOFF     equ 080h
CMD_CHANGEPARAM equ 0B0h
CMD_CHANGEPRG   equ 0C0h
MOD_ALLNOTESOFF equ 07Bh
MAXFACES	equ 400
MAXPOINTS	equ 400
SONGSPEED   	equ 29
XMAX		equ 320
YMIN		equ 21
YMAX		equ 179
SUBRANGE	equ 16
%define ASPECT_RATIO 1.2
CENTERX		equ 160
CENTERY		equ 100

;==============================================================================
;		   structures
;==============================================================================

struc channel
 .del:	resw 1
 .trk:	resb 1
 .ln:	resb 1
 .adr:	resw 1
endstruc

struc matrix
	resd 9
 .size:
endstruc

struc vector
 .x:	resd 1
 .y:	resd 1
 .z:	resd 1
 .size:
endstruc

struc point
 .x:	resw 1
 .y:	resw 1
 .z:	resw 1
 .s:	resw 1
 .size:
endstruc

struc face
	resw 5
 .size: 	
endstruc

;struc object
; .panz: resw 1
; .fanz: resw 1
; .p:	resb point.size*MAXPOINTS
; .f:	resb face.size*MAXFACES
; .size:
;endstruc

struc edges
 .x:	resd 1
 .u:	resd 1
 .v:	resd 1
 .w:	resd 1
 .s:	resd 1
 .size:	
endstruc

struc edge
 .p:	resb vector.size
 .py:	resd 1
 .e:	resb edges.size
 .size:
endstruc

struc poly
	resb edge.size*5
 .size:	
endstruc

;==============================================================================
;		      %macros
;==============================================================================
;***********************************************
;* descript. : start timer interrupt 70/s      *
;* parameter : none			       *
;* sideeffect: all		 	       *
;* back      : none			       *
;***********************************************
%macro		startTimer 0
                ;mov     ax,03508h
                ;int     21h
                ;mov     [word ptr Old08Irqseg],es
                ;mov     [word ptr Old08Irqofs],bx
                ;mov     ax,02508h
                ;mov     dx,offset irqHandler08
                ;int     21h
		
		;mov	bx, 3409 ; 1193180/3409 = 350 ticks per second (*!)
		;call	setTimer

		; start timer event
		mov	ebx, 8400h ; Current Timer setup, Callback method 	
		mov	ecx, 1	 ; 1 tick 
		mov	edx, timer_callback ; timer callback service addr
		mov	eax, 33	; 'systimer'
		int	40h	; TRDOS 386 system call
		jc	loc_err_exit

		mov	[timer_event_number], al 

%endmacro

;***********************************************
;* descript. : stop timer interrupt            *
;* parameter : none			       *
;* sideeffect: all		 	       *
;* back      : none			       *
;***********************************************
%macro		stopTimer 0
                ;push    ds
                ;xor     bx,bx                  ; set timer to default
                ;call    setTimer		; 18.2 ticks per second
                ;mov     ax,02508h              ; restore old IRQ-vector
                ;lds     dx,[Old08Irqptr]
                ;int     21h
                ;pop     ds

		;xor	bx, bx	; set timer to default (18.2 Hz) value
		;call	setTimer

		; Stop timer event
		movzx	ebx, byte [timer_event_number]
		;and	bl, bl
		;jz	short r_t_m ; 0 = error (no timer event)
 		; bh = 0 -> stop timer event
		mov	eax, 33	; 'systimer'
		int	40h	; TRDOS 386 system call
;r_t_m:
%endmacro

;***********************************************
;* descript. : start keyboard handler          *
;* parameter : none			       *
;* sideeffect: all		 	       *
;* back      : none			       *
;***********************************************
%macro		startKBDHandler 0
                ;mov     ax,03509h
                ;int     21h
                ;mov     [word ptr Old09Irqseg],es
                ;mov     [word ptr Old09Irqofs],bx
                ;mov     ax,02509h
                ;mov     dx,offset irqHandler09
                ;int     21h

		; TRDOS 386 already have a CRTL+BRK
		; preview feature to call 'sysexit'
		; /// nothing to do here ! ///
		; 10/12/2016 - Erdogan Tan
		nop
%endmacro

;***********************************************
;* descript. : stop keyboard handler           *
;* parameter : none			       *
;* sideeffect: all		               *
;* back      : none		               *
;***********************************************
%macro		stopKBDHandler 0
                ;push    ds
                ;mov     ax,02509h             ; restore old IRQ-vector
                ;lds     dx,[Old09Irqptr]      ;
                ;int     21h
                ;pop     ds

		; TRDOS 386 already have a CRTL+BRK
		; preview feature to call 'sysexit'
		; /// nothing to do here ! ///
		; 10/12/2016 - Erdogan Tan
		nop
%endmacro

;***********************************************
;* descript. : zero null-initialized data      *
;* parameter : none			       *
;* sideeffect: all		               *
;* back      : none		               *
;***********************************************
%macro		nullData 0
		;mov	di, nullstart
                mov	edi, nullstart
		;mov	cx, nullend-nullstart
                ;mov	ecx, nullend-nullstart ; ??
		xor	eax, eax
                ;rep	stosb
		mov	ecx, (bss_end-nullstart)+3 ; 06/02/2017
		shr	cx, 2
		rep	stosd
%endmacro

;***********************************************
;* descript. : set textmode		       *
;* parameter : none		               *
;* sideeffect: all		               *
;* back      : none		               *
;***********************************************
%macro		set80x25 0
		mov	ax, 3
		;int	10h	; - VIDEO - SET	VIDEO MODE
				; AL = mode
		int	31h	; TRDOS 386 Video interrupt 
%endmacro

;***********************************************
;* descript. : set gfx-mode 320x200            *
;* parameter : none		               *
;* sideeffect: all		               *
;* back      : none		               *
;***********************************************
%macro		set320x200 0
		mov	ax, 13h
		;int	10h		; - VIDEO - SET	VIDEO MODE
					; AL = mode
		int	31h ; TRDOS 386 - Video interrupt
%endmacro

;***********************************************
;* descript. : calculate a smooth colorrange   *
;* parameter : none             	       *
;* sideeffect: all              	       *
;* back	     : none                	       *
;***********************************************
%macro		makePalette 0
		;mov	bx, 3
		mov	ebx, 3
mPcolor:
		;mov	si, colors
		mov	esi, colors
		mov	edi, palette
		xor	dh, dh
		lodsb
		;movzx	cx, al
		movzx	ecx, al ; ??
mPouter:
		push	ecx
		mov	cl, [esi]
		mov	ah, [ebx+esi]
		sub	ax, dx
		push	edx
		cwd
		idiv	cx
		pop	edx
mPinner:
		add	dx, ax
		mov	[edi+ebx-1], dh
		add	di, 3
		loop	mPinner
		add	si, 4
		pop	ecx
		loop	mPouter
		dec	bx
		jnz	short mPcolor
%endmacro

;***********************************************
;* descript. : reset the GM-Port and switch to *
;*             UART mode.		       *
;* parameter : none			       *
;* sideeffect: dx,al		               *
;* back      : none		               *
;***********************************************
%macro		resetGM 0
		mov	dx, GMPort
		mov	al, 0FFh
		;out	dx, al
	
		mov	ah, 1 ; out (byte)
		int	34h ; TRDOS 386 - IOCTL interrupt
		; cl = 0
		dec	ah ; 0
		;sub	cl, cl
resGMbusy1:
		dec	cl
		jz	short rGMerror	;{ timeout }
		;in	al, dx		;{ read acknowledge }
		
		;mov	ah, 0 ; in (byte)
		int	34h ; TRDOS 386 - IOCTL interrupt
		
		test	al, 80h
		jnz	short resGMbusy1
		dec	dx
		;in	al, dx

		;mov	ah, 0 ; in (byte)
		int	34h ; TRDOS 386 - IOCTL interrupt

		cmp	al, 0FEh
		jne	short rGMerror
		inc	dx		;{ switch into UART mode }
resGMbusy2:
		;in	al, dx

		;mov	ah, 0 ; in (byte)
		int	34h ; TRDOS 386 - IOCTL interrupt
		
		test	al, 40h
		jnz	short resGMbusy2
		mov	al, 3Fh
		;out	dx, al

		;mov	ah, 1 ; out (byte)
		inc	ah ; 1
		int	34h ; TRDOS 386 - IOCTL interrupt
rGMerror:
%endmacro

;***********************************************
;* descript. : mute midi channels 0..15        *
;* parameter : none                	       *
;* sideeffect: ax,cx		               *
;* back		 : none                	       *
;***********************************************
%macro		silence 0
		mov	cx, 15 ; 0Fh
Siloop:	
		mov	ax, cx
		add	al, CMD_CHANGEPARAM ; 0B0h
		call	writeGM
		mov	al, MOD_ALLNOTESOFF ; 7Bh
		call	writeGM
		xor	al, al
		call	writeGM
		loop	Siloop
Sinosound:
%endmacro

;***********************************************
;* descript. : create the reactor wall texture *
;* parameter : none		               *
;* sideeffect: ax,bx,cx,di,es                  *
;* back      : none			       *
;* length    : 45 bytes		               *
;***********************************************
%macro		reactorWall 0
		movzx	edi, word [tseg] ; 05/02/2017
		shl	edi, 4 ; *16
		mov	cx, 4096 ; 1000h
rsmloop:
		mov	ax, di
		;and	ax, 0FFFh 
		test	al, 8
		jle	short rsnonot1
		not	al
rsnonot1:
		and	al, 15 ; 0Fh
		mov	bx, ax
		mov	ax, di
		and	ax, 0FFFh ; 18/12/2016
		shr	ax, 6
		test	al, 8
		jle	short rsnonot2
		not	al
rsnonot2:
		and	al, 15 ; 0Fh
		cmp	al, bl
		jle	short rstakeal
		mov	ax, bx
rstakeal:
		add	al, 224 ; 0E0h
		stosb
		loop	rsmloop
%endmacro

;***********************************************
;* descript. : calc background-fractal         *
;* parameter : none		               *
;* sideeffect: ax,bx,cx,si,di,es	       *
;* back      : none			       *
;***********************************************
%macro		createFrac2 0
		movzx	edi, word [tseg+36] ; 05/02/2017
		shl	edi, 4 ;*16
		mov	ebx, edi
		mov	al, 20	; 14h
		call	setFrac
		mov	edi, ebx
		add	di, 64  ; 16/01/2017
		;mov	cx, 4096-64 ; 0FC0h
		mov	ecx, 4096-64 ; ??
		mov	ebx, 4  ; 16/12/2016
cF1loop:
		;mov	bx, 4
		call	rnd
		add	al, [edi-64]  ; byte [es:di-64] (*) 16 bit
		add	al, [edi-63]  ; byte [es:di-63] (*)
		dec	ax
		shr	ax, 1
		stosb
		loop	cF1loop
%endmacro

;***********************************************
;* descript. : calc random noise fractal       *
;* parameter : none		               *
;* sideeffect: ax,bx,cx,si,di,es	       *
;* back      : none			       *
;***********************************************
%macro		createFrac3 0
		movzx	edi, word [tseg+38] ; 05/02/2017
		shl	edi, 4 ; *16
		mov	dword [es_], edi ; 06/02/2017
		mov	al, 3
		call	setFrac
		;mov	cx, 4096 ; 1000h
		mov	ecx, 4096 ; ??
		mov	ebx, ecx
cF3loop:
		;mov	bx, 4096 ; 1000h
		call	rnd
		mov	edi, dword [es_] ; 06/02/2017
		add	di, ax ; 16/01/2017
		inc	byte [edi]
		loop	cF3loop
%endmacro

;***********************************************
;* descript. : init stars (positions and state)*
;* parameter : none			       *
;* sideeffect: eax,bx,cx,edx,si,di,es          *
;* back      : none		               *
;***********************************************
%macro		initStars 0
		;mov	cx, 30 ; 1Eh
		mov	ecx, 30 ; ??
		mov	edi, stars
		xor	ebx, ebx ; ? 18/12/2016
iSloop:	
		mov	bx, 256 ; 100h
		call	rnd
		stosb
		mov	bx, 4096-(64*5) ; 0EC0h
		add	bx, 128 ; 80h
		call	rnd
		add	ax, 64  ; 40h
		stosw
		loop	iSloop
%endmacro

;***********************************************
;* descript. : add effects to fractals	       *
;* parameter : none		               *
;* sideeffect: ax,bx,cx,di,es		       *
;* back      : none		               *
;***********************************************
%macro		effects 0
		; effects
		;mov	cx, 26		; 1Ah
		mov	ecx, 26 ; ??
		mov	esi, aE
		;mov	si, aE
		xor	ebx, ebx
		xor	edi, edi
effmloop:
		push	cx
		mov	bl, byte [esi]	; mseg+effect
		mov	dl, bl
		shr	dl, 4
		and	bl, 0Fh ; 15
		;
		shl	bl, 1
		movzx	ebp, word [ebx+tseg] ; 05/02/2017
		shl	ebp, 4 ; *16
		;
		movzx	cx, byte [esi+2] ; y1
effyloop:
		movzx	bx, byte [esi+1] ; x1
effxloop:
		mov	di, cx
		shl	di, 6
		add	di, bx
		mov	al, dl
		dec	al
		jz	short effect1
		dec	al
		jz	short effect2
		mov	ax, bx
		add	ax, cx
		and	al, 4
		;jz	short effdonot
		jz	short effect1
		mov	al, 152 ; 98h
effdonot:
		jmp	short effect1
effect2:
		mov	al, byte [ebp+edi] ; 16/12/2016
effect1:
		add	al, byte [esi+5]   ; value
		mov	byte [ebp+edi], al ; 16/12/2016
		inc	bl
		cmp	bl, byte [esi+3]   ; x2
		jle	short effxloop
		inc	cx
		cmp	cl, byte [esi+4] ; y2
		jle	short effyloop
		add	si, 6
		pop	cx
		loop	effmloop
%endmacro

;***********************************************
;* descript. : copy fractals and add value     *
;* parameter : none		               *
;* sideeffect: al,cx,di,es,fs		       *
;* back      : none		               *
;***********************************************
%macro		addFractals 0
		mov	esi, aF
		;mov	si, aF
		mov	dl, 4
		xor	ebx, ebx
aFloop:
		mov	bl, dl
		movzx	edi, word [ebx+tseg] ; es: ; 05/02/2017
		shl	edi, 4 ; *16
		lodsw
		mov	bl, al ; 16 bit offset (original)
		;
		movzx	ebp, word [ebx+tseg] ; fs: ; 05/02/2017
		shl	ebp, 4 ; *16 
		;
		;mov	cx, 4096 ; 1000h
		mov	ecx, 4096 ; ??
aFiloop:
		mov	al, [ebp]  ; [fs:di]
		add	al, ah
		stosb
		inc	ebp
		loop	aFiloop
		add	dl, 2
		cmp	dl, 30
		jle	short aFloop
%endmacro

;***********************************************
;* descript. : calculate and initalize textures*
;* parameter : none			       *
;* sideeffect: al,cx,di,es,fs		       *
;* back      : none			       *
;***********************************************
%macro		addLava 0
		movzx	ebp, word [tseg+22] ; 05/02/2017
		shl	ebp, 4 ; *16
		;
		mov	edi, 4095	; 0FFFh
		;mov	cx, 20		; 14h
		mov	ecx, 20 ; ??
		mov	al, 94		; 5Eh
aLyloop:
		push	ecx
		shl	cx, 3
aLxloop:
		push	edi
		push	eax
		;mov	bx, 64		; 40h
		mov	ebx, 64
		call	rnd
		sub	di, ax
		pop	eax
		mov	[ebp+edi], al ; 17/01/2017
		pop	edi
		loop	aLxloop
		pop	ecx
		dec	al
		sub	di, 64 		; 40h
		loop	aLyloop
%endmacro

;***********************************************
;* descript. : calculate and initalize textures*
;* parameter : none		               *
;* sideeffect: al,cx,di,es,fs		       *
;* back      : none		               *
;***********************************************
%macro		initTextures 0
		;mov	bx, 34	; 22h
		mov	ebx, 34
		push	800	; 320h
		push	5
		call	createFrac1
		;mov	bx, 32	; 20h
		mov	ebx, 32
		push	112	; 70h
		push	15	; 0Fh
		call	createFrac1
		createFrac2
		createFrac3
		initStars
		reactorWall
		addFractals
		effects
		addLava
%endmacro

;***********************************************
;* descript. : cycle "range" colors at "base"  *
;* parameter : none		               *
;* sideeffect: ax,(bl),cx,si,di,es             *
;* back      : none			       *
;***********************************************
%macro		colorCycle 0
		base	equ 6*32
                range	equ 32
		
		mov	edi, palette+(base*3)
		mov	esi, edi
		lodsw
		;mov	bl,[esi]  ; works only with fire (no blue)
		inc	esi
		;mov	cx, (range*3-3)
		mov	ecx, (range*3-3) ; ??
		rep movsb
		stosw
		;mov	[edi],bl  ; works only with fire (no blue)
%endmacro

;***********************************************
;* descript. : animate the stars	       *
;* parameter : none			       *
;* sideeffect: ax,bx,cx,dl,si,di,es            *
;* back      : none			       *
;***********************************************
%macro		animStars 0
		_base	equ 7*32

		movzx	edi, word [tseg+2] ; 05/02/2017
		shl	edi, 4 ; *16
		mov	ebp, edi
		call	clearFrac

		;mov	ecx, 30
		;mov	cl, 30	; 1Eh
		mov	ecx, 30 ; ??
		mov	ebx, stars
		;mov	bx, stars
aSoloop:
		dec	byte [ebx]
		mov	ah, [ebx]
		and	ah, 63	; 3Fh
		cmp	ah, 31	; 1Fh
		jbe	short aSnonot
		not	ah
		and	ah, 31	; 1Fh
aSnonot:
		shr	ah, 1
		; 05/02/2017
		movzx	edi, word [ebx+1]
		add	edi, ebp

		push	ecx
		push	ebx

		mov	edx, 64-5 ; 3Bh
		mov	cx, _base*256+0 ; 0E000h
		call	setstarbob

		pop	ebx
		pop	ecx
		add	bx, 3
		loop	aSoloop
%endmacro

;***********************************************
;* descript. : calculate shading tab           *
;* parameter : none		               *
;* sideeffect: ax,bl,cx,di,es                  *
;* back      : none		               *
;***********************************************
%macro		calcShadeTab 0
		mov	edi, shadetab
		xor	bl, bl
cSolp:
		inc	bl
		;xor	cx, cx
		xor	ecx, ecx ; ??
cSilp1:
		mov	al, cl
		and	al, 31	; 1Fh
		mul	bl
		add	ax, ax
		mov	al, cl
		and	al, 224	; 0E0h
		add	al, ah
		stosb
		inc	cl
		cmp	cl, 192 ; 0C0h
		jne	short cSilp1
cSilp2:
		mov	al, cl
		stosb
		inc	cl
		jnz	short cSilp2
		cmp	bl, 128	; 80h
		jne	short cSolp
%endmacro

;***********************************************
;* descript. : expand a song       	       *
;* parameter : si:song base adress	       *
;* sideeffect: ax,bx,cx,dx,si,di               *
;* back      : none                	       *
;***********************************************
%macro		expandSong 0
                mov	esi, credits
                mov	ebx, channels
                mov	edi, songdata
EPSwhile:	lodsw
                dec	al
                js      short EPSendwhile
                mov	[ebx+channel.trk], al ; [ebx+2]
                add	al, CMD_CHANGEPRG ; 0C0h
                call	setinstr
                mov	[ebx+channel.adr], di ; [ebx+4]	
               	call	expand
                xor	al, al
                stosb
                add	bx, 6
                inc	word [tracks]
                jmp	short EPSwhile
EPSendwhile:
%endmacro

;***********************************************
;* descript. : parse the script,rotate and move*
;* parameter : none                	       *
;* sideeffect: all		               *
;* back      : none		               *
;***********************************************
%macro		scriptIt 0
 		; scriptIt
		;mov	cx, [ticker]
		movzx	ecx, word [ticker] ; 22/01/2017
		mov	word [ticker], 0
		or	cx, cx
		jz	sItickerNull
sImloop:
		push	ecx
		mov	esi, zspeed
		;mov	si, zspeed
		;dec	word  [esi+10]	      ;	scriptanz
		dec	word [scriptanz]
		jns	short sIwaitTimer
		;mov	bx, [esi+8]	      ;	scriptptr
		;movzx	ebx, word [esi+8]	
		movzx	ebx, word [scriptptr]
		mov	al, [ebx+script]
		or	al, al
		jz	_exit_
		mov	bx, ax
		and	bl, 7
		;mov	[esi+12], bl	      ;	scriptins
		mov	[scriptins], bl
		dec	bl
		jnz	short sInegateTurn
		; (cmd = NEG ZSTEP)  
		neg	word [zstep]
sInegateTurn:
		and	ax, 0F8h
		add	ax, ax
		;mov	[esi+10], ax	      ; scriptanz
		mov	[scriptanz], ax
		;inc	word [esi+8]	      ; scriptptr
		inc	word [scriptptr]
sIwaitTimer:
		;mov	al, [esi+12]	      ;	scriptins
		mov	al, [scriptins]
		cbw
		sub	ch, ch ; 23/01/2017
		dec	ax
		jnz	short sInoturn
		; (cmd = NEG ZSTEP)  
		mov	bx, [zstep]
		;add	[esi+6], bx	      ; ozw
		add	[ozw], bx
		jmp	short sI_1 ; 23/01/2017	
sInoturn:
		mov	cl, 3
sIrotateLoop:
		dec	ax
		jnz	short sInoIncrement
		; (cmd = INC SPEED or INC XSTEP or INC YSTEP)  
		inc	word [esi]	      ; zspeed, oxw, oyw
		jmp	short sI_1 ; 23/01/2017	 	   	
sInoIncrement:
		dec	ax
		jnz	short sInoDecrement
		; (cmd = DEC SPEED or DEC XSTEP or DEC YSTEP)  
		dec	word [esi]	      ; zspeed, oxw, oyw
		jmp	short sI_1 ; 23/01/2017	 
sInoDecrement:
		inc	esi
		inc	esi
		loop	sIrotateLoop
sI_1: ; 23/01/2017
		;mov	si, zspeed+2	      ; oxw 	
		mov	si, oxw	
		mov	cl, 3
		xor	eax, eax
sIpushloop:
		lodsw			      ; oxw, oyw, ozw	
		sar	ax, 2
		push	eax
		loop	sIpushloop

		imul	ax, word [si-4], 16   ; [oyw]*16 	
		push	eax		        	
		call	calcRotMat

		mov	cl, 3
		xor	esi, esi
sImoveLoop:
		fld	dword [esi+owmat+24]
		fimul	word [zspeed]
		fidiv	word [CONST1792]
		fadd	dword [esi+ob]
		fstp	dword [esi+ob]
		add	si, 4
		loop	sImoveLoop
		pop	ecx
		dec	cx
		jnz	sImloop
sItickerNull:
%endmacro

;***********************************************
;* descript. : rotate all points from o -> rp  *
;* parameter : none                	       *
;* sideeffect: all		               *
;* back      : none		               *
;***********************************************
%macro		rotation 0
		;;mov	cx, [o+object.panz]
		;movzx	ecx, word [o+object.panz] ; ??
		movzx	ecx, word [object.panz]
		;mov	esi, o+object.p
		mov	esi, object.p
		mov	edi, rp
rotmlp:
		;mov	bx, wmat
		mov	ebx, wmat
		mov	dx, 3
rotilp:	
		fild	word [esi+0] ; point.x
		fsub	dword [ob+vector.x]
		fmul	dword [ebx+0]
		fild	word [esi+2] ; point.y
		fsub	dword [ob+vector.y]
		fmul	dword [ebx+4]
		fild	word [esi+4] ; point.z
		fsub	dword [ob+vector.z]
		fmul	dword [ebx+8]
		fadd	
		fadd
		;faddp
		;faddp
		fstp	dword [edi]
		add	di, 4
		;add	edi, 4
		add	bx, 12	; 0Ch
		dec	dx
		jnz	short rotilp
		add	si, 8 ; next point (29/01/2017)
		;add	esi, 8
		loop	rotmlp
%endmacro

;***********************************************
;* descript. : sort faces by z-koord	       *
;* parameter : none		               *
;* sideeffect: ax,bx,cx,dx,si,di,es            *
;* back      : none		               *
;***********************************************
%macro		sortFaces 0
		mov	edi, facei
		push	edi ; facei
		;mov	esi, o+object.f
		;;mov	si, o+object.f
		mov	esi, object.f
		mov	eax, esi ; pointer to faces
		;;mov	cx, [o+object.fanz]
		;movzx	ecx, word [o+object.fanz] ; ??
		movzx	ecx, word [object.fanz]

		xor	ebx, ebx ; ?
sFmloop:
		fldz
		push	ecx
		mov	cx, 4
sFiloop:
		imul	bx, word [esi], 12 ; number of points (of face)
		inc	esi
		inc	esi
		fsub	dword [ebx+rp+vector.z]
		loop	sFiloop
		pop	ecx
		fistp	word [edi] ; z distance (face total) (29/01/2017) 
		inc	edi
		inc	edi
		;stosw		; face address (in 'o+object.f')
		stosw		; face address (in 'object.f')
		add	ax, 10
		inc	esi
		inc	esi
		loop	sFmloop
		;push	edi	; facei+4*(o+object.fanz-1)
		push	edi	; facei+4*(object.fanz-1)
		call	qsort
%endmacro

;***********************************************
;* descript. : animate the door  	       *
;* parameter : none		               *
;* sideeffect: ax,cx,si,di,es                  *
;* back      : none		               *
;***********************************************
%macro		animDoor 0
		;mov	ax, [doortimer]
		movzx	eax, word [doortimer]
		or	ax, ax
		jns	short aDnounder
		xor	ax, ax
		jmp	short alreadydrawed
aDnounder:
		cmp	byte [once], 0
		jne	short alreadydrawed
		inc	byte [once]
		push	ax
		starbackground
		pop	ax
alreadydrawed:
		cmp	ax, 24
		jle	short aDnoover
		mov	ax, 24
aDnoover:
		shl	ax, 6
		;; 05/02/2017
		movzx	edi, word [tseg+26]
		shl	edi, 4 ; *16
		mov	ebp, edi
		movzx	esi, word [tseg+30]
		shl	esi, 4 ; *16
		mov	ebx, esi ; 05/02/2017
		add	si, ax ; 16/01/2017
		;mov	cx, 1024
		mov	ecx, 1024 ; ??
		rep movsw
		mov	esi, ebx
		add	si, 2048 ; 16/01/2017
		sub	si, ax
		push	si
		mov	ch, 4  ; cx = 1024
		rep movsw
		; 16/01/2017
		pop	cx
		and	cx, 4095 ; 0FFFh
		mov	edi, ebp ; 05/02/2017
		add	di, cx
		;
		mov	cx, ax
		xor	ax, ax
		rep stosw
%endmacro

;***********************************************
;* descript. : play a tick of the song	       *
;* parameter : none                	       *
;* sideeffect: ax,bx,cx,dx,si		       *
;* back      : none                	       *
;***********************************************
%macro		playsong 0
		;mov	cx, [tracks]
		movzx	ecx, word [tracks] ; ??
		;mov	si, channels
		mov	esi, channels
PSmloop:
		dec	word [esi+channel.del]
		jg	short PSdelayed
		mov	ax, [esi+channel.trk]
		add	al, CMD_NOTEOFF	; 80h
		call	setnote
		;mov	bx, [esi+channel.adr]
		movzx	ebx, word [esi+channel.adr] ; ??
		mov	ah, 127 	; 7Fh
		cmp	byte [ebx], 0
		jz	short PStrackend
		mov	ah, [ebx]
		mov	[esi+channel.ln], ah
		mov	al, [esi+channel.trk]
		add	al, CMD_NOTEON	; 90h
		call	setnote
		mov	al, [ebx+1]
		mov	bl, SONGSPEED	; 1Dh
		mul	bl
PStrackend:
		mov	[esi+channel.del], ax
		add	word [esi+channel.adr], 2
PSdelayed:
		add	si, 6
		loop	PSmloop
PSnosound:
%endmacro

;***********************************************
;* descript. : dump palette to CRT             *
;* parameter : bl:intensity (0..255)           *
;* sideeffect: ax,es,di,cx,dx                  *
;* back      : none		               *
;***********************************************
%macro		setPalette2 0
		xor	al, al
		mov	dx, 3C8h
		;out	dx, al
		
		mov 	ah, 1 ; out (byte)
		int	34h ; TRDOS 386 - IOCTL interrupt
		
		inc	dx
		mov	esi, palette
		;mov	cx, 768 ; 300h
		mov	ecx, 768 ; ??
_sp2loop:
		;rep outsb
		
		lodsb	
		;mov 	ah, 1 ; out (byte)
		;mov 	dx, 3C9h
		;out 	dx, al
		int	34h ; TRDOS 386 - IOCTL interrupt
		loop	_sp2loop
%endmacro

;***********************************************
;* descript. : clear starbackground            *
;* parameter : none		               *
;* sideeffect: ax,es,di,cx,dx                  *
;* back      : none		               *
;***********************************************
%macro		cls 0
		movzx	edi, word [bseg] ; 05/02/2017
		shl	edi, 4 ; *16
		;
		mov	esi, 0A0000h + (320*5) ; 0A0640h
		;mov	cx, 32000 ; 7D00h
		mov	ecx, 32000 ; ??
clsloop:
		lodsb
		stosb
		stosb
		loop	clsloop
%endmacro

;***********************************************
;* descript. : draw starbackground             *
;* parameter : none		               *
;* sideeffect: ax,es,di,cx,dx                  *
;* back      : none		               *
;***********************************************
%macro		starbackground 0
		movzx	edi, word [bseg] ; 05/02/2017
		shl	edi, 4 ; *16
		;
		mov	ebp, edi
		;mov	cx, 100 ; 64h
		mov	ecx, 100 ; ??
starbackloop:
		push	cx
		;mov	bx, 320*155 ; 0C1C0h
		mov	ebx, 320*155 ; ??
		call	rnd
		add	ax, 320*20  ; 1900h
		; 05/02/2017
		movzx	edi, ax
		add	edi, ebp 
		and	ah, 7
		;mov	dx, 320-5   ; 13Bh
		mov	edx, 320-5 ; ?? 
		mov	cx, 2
		call	setstarbob
		pop	cx
		loop	starbackloop
%endmacro

;***********************************************
;* descript. : create identity matrix	       *
;* parameter : ds:di address                   *
;* sideeffect: cx,di		   	       *
;* back      : none			       *
;***********************************************
%macro		identityMat 0
		mov	ch, 2
iMolp:
		mov	cl, 2
iMilp:
		fldz
		cmp	ch, cl
		jne	short iMwritezero
		fstp	st0
		fld1
iMwritezero:
		fstp	dword [edi]
		add	di, 4
		dec	cl
		jns	short iMilp
		dec	ch
		jns	short iMolp
%endmacro

;=============================================================================
;               entry point
;=============================================================================
;***********************************************
;* descript. : entry point		       *
;* parameter : none		               *
;* sideeffect: all		               *
;* back      : none		               *
;***********************************************

[BITS 32] ; 80386 Protected Mode (32 bit) intructions

[ORG 0] 

start:
		; DIRECT VGA MEMORY ACCESS
		;xor	ebx, ebx
		mov	bh, 5 ; Direct access/map to VGA memory (0A0000h)
		;mov	eax, _video ; 1Fh
		mov	ax, 1Fh ; sys _video ; TRDOS 386 Video functions
		int	40h   ; TRDOS 386 system call

		; eax = 0A0000h
		and	eax, eax
		jz      terminate ; error (eax = 0)

		; clear bss (18/12/2016)
		;mov	edi, bss_start ; ??		
		mov	di, bss_start
		mov	cx, (bss_end - bss_start)/4
		;mov	ecx, (bss_end - bss_start)/4
		xor	eax, eax
		rep	stosd

		;mov	edi, vseg ; ??
		mov	di, vseg
		mov	ax, 1000h
		stosw			; virtual screen address
		add	ax, 1000h
		stosw			; star background address
		add	ax, 1000h
		mov	cx, 20
segloop:				; texture addresses
		stosw
		;add	ax, 100h
		inc	ah
		loop	segloop

		; 22/01/2017
		fninit

		;nullData
		;resetGM
		;expandSong

		call	createWorld

		set320x200

		xchg	ah, al 		; ah = write string = 13h, 
					; al = write mode = 0
		mov	bx, 1Ch
		mov	ebp, omniscent
		mov	cx, omniend-omniscent ; 9
		mov	dx, 106h
		;int	10h		; - VIDEO - WRITE STRING (AT,XT286,PS,EGA,VGA)
					; AL = mode, BL	= attribute if AL bit 1	clear, BH = display page number
					; DH,DL	= row,column of	starting cursor	position, CX = length of string
					; ES:BP	-> start of string
		int	31h ; TRDOS 386 - Video interrupt

		add	bp, cx
		mov	cl, sancend-sanction ; 11h
		mov	dx, 0C01h
		;int	10h		; - VIDEO - WRITE STRING (AT,XT286,PS,EGA,VGA)
					; AL = mode, BL	= attribute if AL bit 1	clear, BH = display page number
					; DH,DL	= row,column of	starting cursor	position, CX = length of string
					; ES:BP	-> start of string
		int	31h ; TRDOS 386 - Video interrupt

		makePalette
		
		initTextures

		calcShadeTab

		mov	dword [oldstack], esp

		startTimer
		startKBDHandler
		cls
mainloop:
		mov	ah, 1	; Check keyboard buffer
		int	32h	; TRDOS 386 Keyboard interrupt
		jnz	_exit_  ; exit

		setPalette2

		scriptIt

		animDoor

		; 05/02/2017
		movzx	edi, word [vseg]
		movzx	esi, word [bseg]
		shl	edi, 4 ; *16
		shl	esi, 4 ; *16
		call	copyseg

		rotation
		sortFaces

jmp short xyz

		xor	eax, eax
		;movzx	ecx, word [o+object.fanz]
		movzx	ecx, word [object.fanz]

		mov	esi, facei
drawloop:
		lodsw
		lodsw
		;mov	ebx, eax ; face address in 'o+object.f'
		mov	ebx, eax ; face address in 'object.f'
		pushad
		call	drawclippedface
		popad
		loop	drawloop

xyz:
		movzx	esi, word [vseg] ; 05/02/2017
		shl	esi, 4 ; *16

movzx esi, word [tseg]
shl esi, 4	
		mov	edi, 0A0000h
		call	copyseg

		jmp	mainloop

loc_err_exit:
_exit_:
		mov	esp, dword [oldstack]
		silence
		stopKBDHandler
		stopTimer
;restore_text_mode:
		set80x25
terminate:
		sys 	_exit   ; INT 40h
here:
		jmp	short here

;==============================================================================
;		interrupt handler
;==============================================================================
;***********************************************
;* descript. : timer routine                   *
;* parameter : none		               *
;* sideeffect: none		               *
;* back      : none		               *
;***********************************************

timer_callback:
		;playsong

		inc	word [ticker]
		inc	byte [twice]
		;and	byte [twice], 7
		;jnz	short tr_1
		
		colorCycle
		animStars
	
		inc	word [doortimer]
tr_1:
		mov	eax, 39	; 'sysrele'
		int	40h	; TRDOS 386 system call
	
;==============================================================================
;		sub routines
;==============================================================================
;***********************************************
;* descript. : draw a the starbob	       *
;* parameter : ds,es: source seg,dest seg      *
;* sideeffect: ax,cx,si,di	               *
;* back      : none		               *
;***********************************************

setstarbob:
		mov	esi, bob
		mov	bl, 5
yloop:
		mov	bh, 5
xloop:
		lodsb
		sub	al, ah
		jle	short aSnodraw
		add	al, ch
		shl	al, cl
		mov	byte [edi], al
aSnodraw:
		;inc	di
		inc	edi
		dec	bh
		jnz	short xloop
		add	edi, edx ; 05/02/2017
		dec	bl
		jnz	short yloop
		retn

;***********************************************
;* descript. : copy 16000 longs ds --> es      *
;* parameter : ds,es: source seg,dest seg      *
;* sideeffect: ax,cx,si,di	               *
;* back      : none		               *
;***********************************************

copyseg:
		;mov	cx, 16000 ; 3E80h
		mov	ecx, 16000 ; ??
		rep movsd
		retn

;***********************************************
;* descript. : expand a part of the song       *
;* parameter : si:base adress		       *
;* sideeffect: si,ax		               *
;* back      : ax=si:new baseadress            *
;***********************************************

expand:
EPwhile: 	mov	cl, byte [esi]
		or	cl, cl
		jz	short EPendwhile
		jns	short EPnote
EPcall:
		push	ecx
		push	esi
		inc	esi
		call	expand
		pop	esi
		pop	ecx
		inc	cl
		jnz	short EPcall
		mov	esi, eax
		jmp	short EPwhile 
EPnote:
		movsw
		jmp	short EPwhile
EPendwhile:
		inc	esi
		mov	eax, esi
		retn

;***********************************************
;* descript. : recursive index quicksort       *
;* parameter : l,r:stack left and right border *
;* sideeffect: ax,bx,cx,dx,si,di               *
;* back      : none		               *
;***********************************************

qsort:
		pop	eax 	; get address
		pop	ecx	; get 2. param r
		pop	ebx	; get 1. param l
		push	eax	; store address

		cmp	ecx, ebx
		;jle	short QSendrek
		jna	short QSendrek
		mov	esi, ebx
		mov	edi, ecx  	
		mov	dx, word [esi]
QSrepeat:
QSwhile1:	cmp	word [esi], dx
		jle	short QSwhile2
		add	esi, 4
		jmp	short QSwhile1
QSwhile2:
		cmp	word [edi], dx
		jnl	short QSwhile2e
		sub	edi, 4
		jmp	short QSwhile2
QSwhile2e:
		cmp	esi, edi
		;jg	short QSnoswap
		;jg	short _QSnoswap ; 29/01/2017
		ja	short _QSnoswap ; 10/02/2017
		lodsd
		xchg	eax, dword [edi]
		mov	dword [esi-4], eax
		sub	edi, 4
QSnoswap:
		cmp	esi, edi
		;jle	short QSrepeat
		jna	short QSrepeat
_QSnoswap: ; 29/01/2017
		push	esi 
		push	ecx
		push	ebx
		push	edi
		call	qsort
		call	qsort
QSendrek:
		retn

;***********************************************
;* descript. : returns a pseudo random number  *
;* parameter : bx=range		               *
;* sideeffect: eax,edx,si		       *
;* back      : ax=rnd(range)                   *
;***********************************************

rnd:
		mov	esi, randommul
		;mov	si, randommul
		lodsd
		mul	dword [esi] ; randomseed
		inc	eax
		mov	[esi], eax  ; randomseed
		lodsw
		lodsw
		mul	bx
		xchg	ax, dx
		retn

;***********************************************
;* descript. : set timer speed to 1193180/AX   *
;*             interrupts per second           *
;* parameter : bx		               *
;* sideeffect: ax		               *
;* back      : none		               *
;***********************************************

setTimer:	; set timer speed to 1193180/BX (TRDOS 386)
		mov	al, 36h
		;out	43h, al		; Timer	8253-5 (AT: 8254.2).

		mov	ah, 1 ; out (byte)
		mov	dx, 43h
		int	34h ; TRDOS 386 - IOCTL interrupt

		mov	al, bl
		;out	40h, al		; Timer	8253-5 (AT: 8254.2).
		
		mov	dx, 40h
		;mov	ah, 1 ; out (byte)
		int	34h ; TRDOS 386 - IOCTL interrupt

		mov	al, bh
		;out	40h, al		; Timer	8253-5 (AT: 8254.2).
		
		;mov	ah, 1 ; out (byte)
		;mov	dx, 40h
		int	34h ; TRDOS 386 - IOCTL interrupt

		retn

;***********************************************
;* descript. : send a byte to the GM-Port      *
;* parameter : al:midi command                 *
;* sideeffect: dx		               *
;* back      : none		               *
;***********************************************

writeGM:
		mov	dx, GMPort  ; 331h
		push	cx
		push	ax
		xor	cl, cl
busy:
		dec	cl
		jz	short timeOut
		;in	al, dx

		mov	ah, 0	; in (byte)
  		int	34h	; TRDOS 386 - IOCTL interrupt
		
		test	al, 40h
		jnz	short busy

timeOut:				; CODE XREF: writeGM+8j
		pop	ax
		pop	cx
		dec	dx
		;out	dx, al
		
		mov	ah, 1	; out (byte)
  		int	34h	; TRDOS 386 - IOCTL interrupt

		retn

;***********************************************
;* descript. : send NOTEON command, volume 127 *
;* parameter : al:channel;ah:note              *
;* sideeffect: dx,al		               *
;* back      : none		               *
;***********************************************

setnote:
		call	setinstr
		mov	al, 127	; 7Fh
		call	writeGM
		retn

;***********************************************
;* descript. : send CHANGEPRG command	       *
;* parameter : al:channel;ah:instrument        *
;* sideeffect: dx,al		               *
;* back      : none		               *
;***********************************************

setinstr:
		call	writeGM
		mov	al, ah
		call	writeGM
		retn

;***********************************************
;* descript. : clear/set the fractal es: to al *
;* parameter : al,es		               *
;* sideeffect: ax,cx,di,es  	               *
;* back      : none			       *
;***********************************************

clearFrac:
		xor	eax, eax
setFrac:
		;mov	cx, 4096 ; 1000h
		mov	ecx, 4096 ; ??
		rep stosb
		retn

;***********************************************
;* descript. : calc shade bob fractal          *
;* parameter : es:seg;num,rad:stack            *
;* sideeffect: all			       *
;* back      : none			       *
;***********************************************

createFrac1:
		rad	equ 8  ; arg 1 in [esp+4]
		num	equ 12 ; arg 2 in [esp+8]

		push	ebp
		mov	ebp, esp
		;
		; 05/02/2017
		movzx	edi, word [ebx+tseg] ; es:
		shl	edi, 4 ; *16
		mov	dword [es_], edi  ; 16/01/2017
		call	clearFrac
		;mov	si, circletab
		mov	esi, circletab
		;mov	dx, word [ebp+rad]
		mov	edx, dword [ebp+rad]		
		mov	al, dl
		imul	dl
		;mov	di, ax
		mov	bx, ax ; 16/01/2017
		;mov	cx, dx
		;add	cx, cx
		mov	ecx, edx ; ??
		add	ecx, ecx ; ??
CCTloop:
		mov	al, dl
		imul	dl
		neg	ax
		;add	ax, di
		add	ax, bx ; 16/01/2017
		mov	word [esi], ax
		fild	word [esi]
		fsqrt
		fistp	word [esi]
		inc	esi
		inc	esi
		dec	dx
		loop	CCTloop

		mov	cx, word [ebp+num]
SBloop1:
		push	ecx
		mov	ebx, 4096 ; 1000h
		call	rnd
		movzx	edi, ax ; 05/02/2017
		mov	si, circletab
		mov	cx, word [ebp+rad]
		;add	cx, cx
		add	ecx, ecx ; ??
		mov	ebx, dword [es_]
SBloop2:
		push	ecx
		lodsw
		mov	cx, ax
		add	cx, cx
		jz	short SBskip
		push	edi
		sub	di, ax
SBloop3:
		and	di, 4095  ; 0FFFh
		inc	byte [edi+ebx] ; 17/01/2017
		inc	edi
		loop	SBloop3
		pop	edi
SBskip:
		add	di, 64 ; 40h
		pop	ecx
		loop	SBloop2
		pop	ecx
		loop	SBloop1
		pop	ebp
		ret	8

;***********************************************
;* descript. : draw a perpective-texturemapped *
;*	       and g.-shaded n-sided polygon   *
;* parameter : far ptr to poly, sides, textnum *
;* sideeffect: all			       *
;* back      : none			       *
;* length    : 700 bytes		       *
;***********************************************

scansubtextpoly:
		; 30/01/2017
		col	equ 8   ; arg 1, [esp+4]  ; dcf.col value
		n	equ 12  ; arg 2, [esp+8]  ; dcf.j value
		pol	equ 16  ; arg 3, [esp+12] ; dcf.p2 address

		; 06/02/2017
 		push	ebp
		mov	ebp, esp

		; 21/01/2017
		mov	eax, 32767
		mov	edx, eax
		mov	ebx, eax
		neg	bx	 ; -32767 ; 8001h
		mov	esi, ebx ; -32767
		
		;edi = 32 bit address (in stack) /// 18/01/2017		
		mov	edi, dword [ebp+pol] ; [ebp+16] ; dcf.p2 ; face structure

		xor	ecx, ecx
minmax:
		cmp	ax, word [edi+2+edge.e+edges.x] ; [edi+12h]
		jle	short noswap1
		mov	ax, word [edi+2+edge.e+edges.x] ; [edi+12h]
noswap1:
		cmp	bx, word [edi+2+edge.e+edges.x] ; [edi+12h]
		jge	short noswap2
		mov	bx, word [edi+2+edge.e+edges.x] ; [edi+12h]
noswap2:
		cmp	dx, word [edi+edge.py]  ; [edi+0Ch]
		jle	short noswap3
		mov	dx, word [edi+edge.py]  ; [edi+0Ch]
		mov	word [sstp.l], cx
		mov	word [sstp.r], cx
noswap3:
		cmp	si, word [edi+edge.py]  ; [edi+0Ch]
		jge	short noswap4
		mov	si, word [edi+edge.py]  ; [edi+0Ch]
noswap4:
		add	di, 36 ; 24h
		inc	cx
		cmp	cx, word [ebp+n] ; [ebp+12]
				   ; dcf.j ; number of visible edges/points
		jne	short minmax

		cmp	bx, 0
		jl	exitDraw
		cmp	ax, XMAX  ; 140h
		jg	exitDraw

		cmp	si, YMIN  ; 15h
		jl	exitDraw
		cmp	dx, YMAX  ; 0B3h
		jg	exitDraw
		mov	word [sstp.miny], dx
		mov	word [sstp.maxy], si

		;{ down clipping }
		cmp	word [sstp.maxy], YMAX ; 0B3h
		jle	short noclipdown
		mov	word [sstp.maxy], YMAX ; 0B3h
noclipdown:
		mov	ax, word [sstp.miny]
		cmp	ax, word [sstp.maxy]
		je	exitDraw
		mov	word [sstp.y], ax
		; 05/02/2017
		mov	ebx, dword [ebp+col]	; [ebp+8]
					 ; dcf.col ; shade/color index
		shl	bx, 1
		;
		movzx	eax, word [vseg]
		shl	eax, 4 ; *16
		mov	dword [es_], eax
		movzx	eax, word [ebx+tseg]
		shl	eax, 4 ; *16
		mov	dword [fs_], eax
for:
		movzx	eax, word [sstp.y]
		cmp	ax, word [sstp.maxy]
		jg	exitDraw
		je	exitwhile2
while1:
		;mov	ax, word [sstp.y]
		;cmp	ax, word [sstp.maxy]
		;jge	short while2	
		; 05/02/2017
		imul	bx, word [sstp.l], 36
		movzx	esi, bx
		add	esi, dword [ebp+pol]	; [ebp+16]

		cmp	ax, word [esi+edge.py]	; [esi+0Ch]
		jne	short while2

		mov	bx, word [sstp.l]
		dec	bx
		jge	short nounder
		mov	bx, word [ebp+n]	; [ebp+12]
				 	; dcf.j ; visible edges/points
		dec	bx
nounder:
		mov	word [sstp.l], bx
		xor	edi, edi
		call	calcDeltas
		mov	ax, word [sstp.y]
		cmp	ax, word [sstp.maxy]
		jge	short exitwhile2	
		jmp	short while1
while2:
		;mov	ax, word [sstp.y]
		cmp	ax, word [sstp.maxy]
		jge	short exitwhile2
		; 05/02/2017
		imul	bx, word [sstp.r], 36
		movzx	esi, bx
		add	esi, dword [ebp+pol]	; [ebp+16]

		cmp	ax, word [esi+edge.py]	; [esi+0Ch]
		jne	short exitwhile2

		mov	bx, word [sstp.r]
		inc	bx
		cmp	bx, word [ebp+n]	; [ebp+12]
		jl	short noover
		;xor	bx, bx
		xor	ebx, ebx
noover:
		mov	word [sstp.r], bx
		mov	edi, 20  ; 14h
		call	calcDeltas
		;
		mov	ax, word [sstp.y]
		jmp	short while2
exitwhile2:
		;{ up clipping }
		cmp	word [sstp.y], YMIN	; 15h
		jl	clipup
		xor	ebx, ebx
		xor	ecx, ecx
		mov	bx, word [sstp.edg+2+edges.x]
		mov	word [sstp.mx1], bx 
		mov	cx, word [sstp.edg+20+2+edges.x]
		mov	word [sstp.mx2], cx
		sub	cx, bx
		jz	exitol
		cmp	word [sstp.mx2], 0
		jle	exitol
		cmp	word [sstp.mx1], XMAX ; 140h
		jg	exitol

		neg	bx
		jns	short myelse
		xor	bx, bx
		jmp	short myendif
_nodivbyzero:
		mov	eax, dword [edi+sstp.del+40]
		jmp	short nodivbyzero
myelse:
		mov	word [sstp.mx1], 0
myendif:
		mov	edi, 16 ; 10h
addloop1:
		;{ calculate deltas }
		mov	eax, dword [edi+sstp.edg+20]
		sub	eax, dword [edi+sstp.edg]
		cdq
		;jcxz	nodivbyzero
		jcxz	_nodivbyzero
		idiv	ecx
		mov	dword [edi+sstp.del+40], eax
nodivbyzero:
		;{ left clipping }
		mov	eax, dword [edi+sstp.del+40]
		imul	ebx
		add	eax, dword [edi+sstp.edg]
		mov	dword [edi+sstp.edg+40], eax
		sub	di, 4
		jnz	short addloop1

		mov	ax, word [sstp.del+40+16]
		mov	word [dels_pos_w], ax

		;{ right clipping }
		cmp	word  [sstp.mx2], XMAX
		jle	short norightclip
		mov	word  [sstp.mx2], XMAX
norightclip:
		imul	di, word [sstp.y], 320
		add	di, word [sstp.mx1]
		
		mov	bx, 256 ; 100h
		mov	eax, dword [sstp.edg+40+edges.u]
		imul	ebx
		idiv	dword [sstp.edg+40+edges.w]
		mov	word [sstp.uu2], ax
		mov	eax, dword [sstp.edg+40+edges.v]
		imul	ebx
		idiv	dword [sstp.edg+40+edges.w]
		mov	word [sstp.vv2], ax
outloop:
		mov	cx, word [sstp.mx2]
		sub	cx, word [sstp.mx1]
		jle	exitol
		cmp	cx, SUBRANGE ; 10h
		jle	short lastSeg
		mov	cx, SUBRANGE ; 10h
lastSeg:
		;{ uu1:=uu2 }
		;{ vv1:=vv2 }
		mov	eax, dword [sstp.vv2]
		mov	dword [sstp.vv1], eax

		mov	eax, dword [sstp.del+40+edges.u]
		imul	ecx
		add	dword [sstp.edg+40+edges.u], eax
		mov	eax, dword [sstp.del+40+edges.v]
		imul	ecx
		add	dword [sstp.edg+40+edges.v], eax
		mov	eax, dword [sstp.del+40+edges.w]
		imul	ecx
		add	dword [sstp.edg+40+edges.w], eax

		mov	bx, 256 ; 100h
		mov	eax, dword [sstp.edg+40+edges.u]
		imul	ebx
		idiv	dword [sstp.edg+40+edges.w]
		mov	word [sstp.uu2], ax
		mov	eax, dword [sstp.edg+40+edges.v]
		imul	ebx
		idiv	dword [sstp.edg+40+edges.w]
		mov	word [sstp.vv2], ax

		mov	ax, word [sstp.uu2]
		sub	ax, word [sstp.uu1]
		cwd
		idiv	cx
		mov	word [ddu_pos_w], ax

		mov	ax, word [sstp.vv2]
		sub	ax, word [sstp.vv1]
		cwd
		idiv	cx
		mov	word [ddv_pos_w], ax

		mov	si, word [sstp.vv1]
		mov	dx, word [sstp.uu1]
		mov	ax, word [sstp.edg+40+16]
innerloop:
 		; 05/02/2017
		movzx	ebx, si
		xor	bl, bl
		shr	bx, 2
		add	bl, dh
		add	ebx, dword [fs_]
		movzx	ebx, byte [ebx] ; [fs:bx]
		or	bl, bl
		jz	short dels_pos
		mov	bh, ah
		mov	bl, byte [ebx+shadetab]

		push	esi
		movzx	esi, di
		add	esi, dword [es_]
		mov	byte [esi], bl	; [es:di] 
		pop	esi
dels_pos:	
		add	ax, word [dels_pos_w] ;{word ptr dels}
ddu_pos:	
		add	dx, word [ddu_pos_w]  ;{word ptr ddu }
ddv_pos:	
		add	si, word [ddv_pos_w]  ;{word ptr ddv }

		inc	di	
		loop	innerloop

		mov	word [sstp.edg+40+16], ax
		add	word [sstp.mx1], SUBRANGE
		jmp	outloop
exitol:
clipup:		mov	edi, 36 ; 24h
addloop:
		mov	eax, dword [edi+sstp.del]
		add	dword [edi+sstp.edg], eax
		sub	di, 4
		jns	short addloop
		inc	word [sstp.y]
		jmp	for
exitDraw:
		pop	ebp
		ret	12

  ;***********************************************
  ;* descript. : calc deltas for vertical interp.*
  ;* parameter : none			         *
  ;* sideeffect: all		 	         *
  ;***********************************************

calcDeltas:
		imul	dx, bx,	36
		mov	ebx, esi
		movzx	esi, dx
		add	esi, dword [ebp+pol]  ; [ebp+16]
		;
		mov	ax, word [esi+12]
		sub	ax, word [sstp.y]
		movsx	eax, ax
		mov	dword [sstp.dy], eax
		mov	cx, 5
cDloop:
		mov	edx, dword [ebx+16]
		mov	dword [edi+sstp.edg], edx
		mov	eax, dword [esi+16]
		sub	eax, edx
		cdq
		cmp	word [sstp.dy], 0
		je	short cDskip
		idiv	dword [sstp.dy]
		mov	dword [edi+sstp.del], eax
cDskip:
		mov	edx, 4
		add	edi, edx ; +4
		add	esi, edx ; +4
		add	ebx, edx ; +4
		loop	cDloop
		retn

;***********************************************
;* descript. : clip a poly at the viewplane,   *
;*             project and draw it	       *
;* parameter : bx:adress of the face	       *
;* sideeffect: all		 	       *
;* back      : none			       *
;***********************************************

drawclippedface:
		; 06/02/2017
		mov	esi, uvtab
		;mov	si, uvtab
		xor	edi, edi
		;mov	ecx, 4
		mov	cx, 4
dCFinitloop:
		;push	ebx	; face addr (in 'o+object.f')(29/01/2017)
		push	ebx	; face addr (in 'object.f')
		;movzx	ebx, word [ebx]
		mov	bx, word [ebx] ; point index into 'rp:' ? (29/01/2017)

		push	ebx
		imul	bx, bx, 12 ; (point vector size = 12 bytes)
		add	ebx, rp	  ; addr of rotated point vects (29/01/2017)
		mov	eax, dword [ebx]
		; vector(4-cx).x
		mov	dword [edi+dcf.p0+0], eax
		; vector(4-cx).y
		mov	eax, dword [ebx+4]
		mov	dword [edi+dcf.p0+4], eax

		fld	dword [ebx+8]
		; vector(4-cx).z
		fst	dword [edi+dcf.p0+8]
		fistp	word [dcf.h]	; dcf.h = z distance
		pop	ebx

		mov	ax, word [dcf.h]
		add	ax, 512	; 200h
		js	dCFbackclip   ; not visible ? (29/01/2017) 

		cmp	ax, 511 ; 1FFh
		jle	short intensityOK
		mov	ax, 511 ; 1FFh	; maximum z distance (dept) ?
intensityOK:
		shl	bx, 3 ; point index * 8
		xor	edx, edx
		shl	ax, 7
		;mul	word [ebx+o+6+object.p]	; [ebx+o+6+4]
		mul	word [ebx+6+object.p] ; 10/02/2017
		; edges(4-cx).s
		mov	dword [edi+dcf.p0+32], edx

		xor	ah, ah
		mov	al, byte [esi+4]
		shl	eax, 16	; 10h
		; edges(4-cx).v
		mov	dword [edi+dcf.p0+24], eax

		lodsb
		shl	eax, 16	; 10h
		; edges(4-cx).u
		mov	dword [edi+dcf.p0+20], eax

		pop	ebx
		inc	ebx
		inc	ebx
		add	di, 36	; 24h  ; size of edge
		;loop	dCFinitloop
		dec	cx
		jnz	dCFinitloop

		; end of p1, p2, p3, p4 point dimensioning of face
		; 
		; p1 ...... p2
		;  .	    .	
		;  . shade  .
		;  .        .
		; p3 ...... p4
		;
		; p1 (x,y,z) ... p4 (x,y,z)
		;

		mov	ax, word [ebx]		; shade
		mov	word [dcf.col], ax

		xor	ebx, ebx
		mov	word [dcf.j], bx

		; vector(3).z
		fld	dword [dcf.p0+108+8]
		ftst
		;fstsw	ax
		fnstsw	ax
		fstp	st0
		sahf
		jae	short isFalse
		dec	bx
isFalse:
		mov	byte [dcf.is_in], bl
		xor	esi, esi
		xor	edi, edi 
forloop:
		; vector(0-3).z
		fld	dword [esi+dcf.p0+8]
		ftst
		;fstsw	ax
		fnstsw	ax
		fstp	st0
		sahf
		jae	short elseFall

		cmp	byte [dcf.is_in], 0FFh ; -1 ; true
		je	short inside
		call	clipsub
		; { OUT / IN }
		not	byte [dcf.is_in]
inside:
		push	edi
		push	esi
		;lea	edi, [edi+dcf.p2]
		;lea	esi, [esi+dcf.p0]
		add	edi, dcf.p2
		add	esi, dcf.p0

		mov	cx, 18	; 12h
		rep movsw		; { IN / IN }

		pop	esi
		pop	edi
		add	di, 36	; 24h
		inc	word [dcf.j]
		jmp	short dCFendif
elseFall:
		cmp	byte [dcf.is_in], 0FFh
		jne	short outside
		call	clipsub
		; { IN / OUT }
		not	byte [dcf.is_in]
outside:
dCFendif:	add	si, 36 ; 24h
		cmp	si, 4*36 ; 90h
		jne	short forloop

		mov	cx, word [dcf.j]
		cmp	cx, 2
		jl	dCFnodraw
		xor	edi, edi
dCFloop:
		fild	word [CONST13]
		fsub	dword [edi+dcf.p2+8]
		fidiv	word [CONST160]
		
		fld	dword [edi+dcf.p2+4]
		fdiv	st0, st1
		fiadd	word [CONST100]
		fistp	dword [edi+dcf.p2+12]
		
		fld	dword [edi+dcf.p2]
		fmul	dword [ASPECT_PLACE]
		fdiv	st0, st1
		fiadd	word [CONST160]
		frndint
		fimul	dword [CONST65536]
		fistp	dword [edi+dcf.p2+16]

		fild	dword [edi+dcf.p2+20]
		fdiv	st0, st1
		fistp	dword [edi+dcf.p2+20]
		
		fild	dword [edi+dcf.p2+24]
		fdiv	st0, st1
		fistp	dword [edi+dcf.p2+24]
		
		fild	dword [CONST65536]
		fdiv	st0, st1
		fistp	dword [edi+dcf.p2+28]
		
		fstp	st0
		add	di, 36 ; 24h
		loop	dCFloop
		;dec	cx
		;jnz	dCFloop

		;lea	edi, [dcf.p2]
		mov	edi, dcf.p2
		push	edi
		push	word [dcf.j] 
		push	word [dcf.col]
		call	scansubtextpoly
dCFnodraw:
dCFbackclip:
		retn

clipsub:
		; 05/02/2017
		push	esi
		push	edi
		lea	eax, [esi-36]
		cmp	eax, 0
		jge	short cSnounder
		mov	eax, 108 ; 6Ch
cSnounder:
		fld	dword [esi+dcf.p0+8]
		fld	st0
		xchg	eax, edi
		fsub	dword [edi+dcf.p0+8]
		xchg	eax, edi
		fdivp	st1, st0
		;fdiv

		mov	ebx, cliptab
		mov	cx, 6
		xor	edx, edx
dCFclipLoop2:
		xchg	eax, edi
		fld	dword [edi+dcf.p0]
		xchg	eax, edi
		fsub	dword [esi+dcf.p0]
		fmul	st0, st1
		fadd	dword [esi+dcf.p0]
		fstp	dword [edi+dcf.p2]

		mov	dl, byte [ebx]
		inc	ebx
		add	edi, edx
		add	esi, edx
		add	eax, edx
		loop	dCFclipLoop2
		fstp	st0
		pop	edi
		pop	esi
		inc	word [dcf.j]
		;add	edi, 36
		add	di, 36 ; 24h
		retn


;***********************************************
;* descript. : rotate point over one axis      *
;* parameter : st(0):angle, [ds:si] ptr to     *
;*	       1.koord.,[ds:bx] ptr to 2.koord.*
;* sideeffect: empty copro-stack               *
;* back      : none			       *
;***********************************************

rotateAxis:
		fldpi				;{ PI,a}
		fmulp	st1, st0		;{ PI*a}	
		;fmul
		fidiv	dword [CONST65536]	;{ PI*a/65536}
		fsincos				;{ cos,sin}
		fld	st0			;{ cos,cos,sin}
		fmul	dword [esi] 		;{ y*cos,cos,sin}
		fld	st2			;{ sin,y*cos,cos,sin}
		fmul	dword [ebx]		;{ z*sin,y*cos,cos,sin}
		fsubp	st1, st0		;{ y*cos-z*sin,cos,sin}
		fxch	st2			;{ sin,cos,y*cos-z*sin}
		fmul	dword [esi]		;{ y*sin,cos,y*cos-z*sin}
		fxch	st1			;{ cos,y*sin,y*cos-z*sin}
		fmul	dword [ebx]		;{ z*cos,y*sin,y*cos-z*sin}
		faddp	st1, st0		;{ y*sin+z*cos,y*cos-z*sin}
		fstp	dword [ebx]		;{ y*cos-z*sin}
		fstp	dword [esi]		;{}
		retn

;***********************************************
;* descript. : rotate point		       *
;* parameter : a,b,c:angles,adr:address        *
;* sideeffect: all		 	       *
;* back      : none			       *
;***********************************************

xyzRotate:
		adr	equ 8   ; arg 1, [esp+4]
		c	equ 12	; arg 2, [esp+8]	
		b	equ 16  ; arg 3, [esp+12]
		a	equ 20  ; arg 4, [esp+16]

		push	ebp
		mov	ebp, esp
	
		mov	edi, [ebp+adr]
		fild	word [ebp+a]
		lea	ebx, [edi+8]
		lea	esi, [edi+4]
		call	rotateAxis
		fild	word [ebp+b]
		lea	ebx, [edi]
		lea	esi, [edi+8]
		call	rotateAxis
		fild	word [ebp+c]
		lea	ebx, [edi+4]
		lea	esi, [edi]
		call	rotateAxis

		pop	ebp
		ret	16

;***********************************************
;* descript. : calculate world matrix	       *
;* parameter : x-,y-,z-angle,neig:stack	       *
;* sideeffect: all		 	       *
;* back      : none			       *
;***********************************************

calcRotMat:
		neig	equ 8   ; arg 1, [esp+4]
		zw	equ 12	; arg 2, [esp+8]	
		yw	equ 16  ; arg 3, [esp+12]
		xw	equ 20  ; arg 4, [esp+16]

		push	ebp
		mov	ebp, esp

		mov	edi, nwmat
		identityMat
		xor	edi, edi
cRMolp:
		push	edi
		push	dword [ebp+xw]
		push	dword [ebp+yw]
		push	dword [ebp+zw]
		;add	edi, nwmat
		add	di, nwmat
		push	edi
		call	xyzRotate
		pop	edi
		xor	ebx, ebx
cRMilp:
		fld	dword [edi+nwmat]
		fmul	dword [ebx+owmat]
		fld	dword [edi+nwmat+4]
		fmul	dword [ebx+owmat+12]
		fld	dword [edi+nwmat+8]
		fmul	dword [ebx+owmat+24]
		fadd
		fadd
		fst	dword [ebx+edi+owmat]
		fstp	dword [ebx+edi+wmat]
		add	bx, 4
		cmp	bl, 12
		jne	short cRMilp
		add	di, 12
		cmp	di, 36
		jne	short cRMolp

		mov	esi, wmat
		mov	cx, 3
cRMneigloop:
		fild	word [ebp+neig]
		lea	ebx, [esi+12]
		call	rotateAxis
		add	si, 4
		loop	cRMneigloop

		pop	ebp
		ret	16

;***********************************************
;* descript. : create the world		       *
;* parameter : none			       *
;* sideeffect: all		               *
;* back      : none			       *
;***********************************************

createWorld:
		; 06/02/2017
		mov	esi, world
		;mov	cx, 4
		mov	ecx, 4 ; ??
cWworldLoop:
		push	ecx
		push	esi
		mov	edi, p
		mov	ebx, pr
		mov	si, print
		mov	cl, 15 ; 0Fh
cWinitStartRoom:
		push	ecx
		mov	cl, 3
cWinnerLoop:
		lodsb  ; byte data (to be converted to dword) from the 'print:'
		cbw    ; convert byte to word with sign (0E0h -> FFE0h)	
		stosw  ; store world coordinate/dimension as integer (word), to 'p:' 
		fild	word [edi-2]
		fstp	dword [ebx] ; store coordinate as floatpoint (29/01/2017)
		add	bx, 4 ; next dimension (x,y,z) in 'pr:'
		loop	cWinnerLoop
		pop	ecx
		mov	ax, 127*256 ; 7F00h ;  4th dimension in 'p:' (29/01/2017)
		stosw
		loop	cWinitStartRoom
		pop	esi
cWmainLoop:
		lodsb	; the byte from 'world:' for shade and direction ( 29/01/2017)
		cmp	al, 255 ; 0FFh
		je	cWexit  ; end of stage (1 to 4) (29/01/2017)

		mov	bh, al  ; High 4 bits for shading (29/01/2017)
		and	bx, 7000h
		add	bh, 15 ; 0Fh
		mov	word [cw.shade], bx
		and	ax, 0Fh ; 15   ; Low 4 bits for direction (29/01/2017)
		mov	word [cw.direc], ax

		xor	ebx, ebx
cWsideLoop:
		test	bl, 4
		jz	short cWfirstNibble
		lodsb
		and	al, 0Fh ; 15
		jmp	short cWsecondNibble
cWfirstNibble:
		mov	al, byte [esi]
		shr	al, 4
cWsecondNibble:
		xor	edi, edi ; 10/02/2017 (is this necessary?)
		xor	ah, ah
		dec	ax
		js	short cWnoWall ; ax = 0 -> ax = 0FFFFh (29/01/2017)
		;imul	di, word [o+object.fanz], 10 ; 0Ah
		imul	di, word [object.fanz], 10 ; 10/02/2017
		;add	di, o+object.f ; base address + offset
		;add	di, object.f ; base address + offset		
		add	edi, object.f ; 10/02/2017
		;inc	word [o+object.fanz] ; faces = faces + 1
		inc	word [object.fanz] ; faces = faces + 1
		mov	word [edi+8], ax ; 4th word is shading value (29/01/2017)

		push	ebx
		push	esi
		mov	cl, 4
cWaddPointloop:
		;movsx	esi, byte [ebx+cube] ; cube coordinate offset (29/01/207)
		;xor	esi, esi ; 10/02/2017
		movsx	si, byte [ebx+cube]
		add	esi, p ; + base address (p:) (29/01/2017)

		push	edi
		;mov	edi, o+object.p  ; p area of object structure (in o:)
		mov	edi, object.p ; 10/02/2017
		push	ecx
		;mov	cx, word [o+object.panz] ; number of points (for object.p)
		mov	cx, word [object.panz] ; 10/02/2017
		xor	ax, ax
		jcxz	cWfirstPoint
cWsearchPointLoop: ; check point coordinates are same or not (29/01/2017)
		mov	edx, dword [esi]
		cmp	edx, dword [edi]
		jne	short cWdifferent
		mov	dx, word [esi+4]
		cmp	dx, word [edi+4]
		je	short cWpointExists
cWdifferent:
		inc	ax ; number of different points (of object)
		add	di, 8
		loop	cWsearchPointLoop
cWfirstPoint:
		movsd
		movsd
		;inc	word [o+object.panz] ; points = points + 1
		inc	word [object.panz] ; 10/02/2017
cWpointExists:
		pop	ecx
		pop	edi
		stosw   ; store num of different points (29/01/2017)
			; in the Xth word of face structure (5 words)
			; (Xth word of 'object.f', X = 4-CL)
		inc	ebx
		loop	cWaddPointloop
		pop	esi
		pop	ebx
cWnoWall:
		add	bx, 4
		cmp	bx, 24 ; 18h
		jne	cWsideLoop

		;xor	edi, edi ; 10/02/2017
		imul	di, word [cw.direc], 12
		;movsx	edi, di ; 05/02/2017
		mov	cl, 3
		;mov	ebx, pr+96
		mov	bx, pr+96 ; 24th dword of 'pr:'
cWaddStepLoop:
		fld	dword [ebx+72] ; [ebx+48h]
		fadd	dword [ebx+edi]
		fstp	dword [ebx+72]
		add	bx, 4
		loop	cWaddStepLoop

		cmp	byte [esi-4], 0
		jge	short cWsimpleRoom

		mov	bx, pr
		mov	cl, 14 ; 0Eh
cWrotloop:
		pushad
		mov	cl, 3
		mov	dl, byte [esi]
cWpushLoop:
		xor	eax, eax
		shr	dl, 1
		jnc	short cWnoRot
		mov	ah, byte [esi]
		;and	ax, 0F000h
		and	ah, 0F0h
		;push	ax
		;jmp	short cWendIf
cWnoRot:
		;push	0 ; arg 2 (c), arg 3 (b), arg 4 (a)
		push	eax
cWendIf:
		loop	cWpushLoop
		push	ebx ; arg 1 (addr)
		call	xyzRotate
		popad
		add	bx, 12 ; 0Ch
		loop	cWrotloop
		inc	esi
cWsimpleRoom:
		mov	bx, word [cw.direc]
		shl	bx, 2
		mov	cl, 4
cWpointCopyLoop:
		pushad
		;movsx	esi, byte [ebx+cube]
		;xor esi, esi ; 10/02/2017
		movsx	si, byte [ebx+cube]
		mov	eax, esi
		add	esi, p ; + base address of 'p:'
		xor	bl, 7
		;movsx	edi, byte [ebx+cube]
		;xor	edi, edi ; 10/02/2017
		movsx	di, byte [ebx+cube]
		add	edi, p ; + base address of 'p:'
		push	esi 
		movsd
		movsd
		pop	esi

		mov	ebx, eax
		shr	ebx, 1
		add	ebx, eax
		mov	edi, pr ; + base address of 'pr:'
		mov	cl, 3
cWSround:
		fld	dword [ebx+edi]
		fadd	dword [edi+168]  ; [edi+0A8h]
		fistp	word [esi] ; world coordinate/dimension
		add	di, 4
		inc	esi
		inc	esi
		loop	cWSround
		mov	ax, word [cw.shade]
		mov	word [esi], ax ; 4th word
		popad
		inc	ebx
		loop	cWpointCopyLoop
		jmp	cWmainLoop
cWexit:
		pop	ecx
		dec	cx
		jnz	cWworldLoop
		retn

; 17/01/2017
dels_pos_w:	dw 1111h
ddu_pos_w:	dw 1111h
ddv_pos_w:	dw 1111h

prg_msg:
		db	'ERDOGAN TAN - TRDOS 386 VGA Test - SNCOMNI.PRG'
		db	0Dh, 0Ah
		db	'06/02/2017'
		db	0Dh, 0Ah
		db	0 

;=============================================================================
;               preinitialized data
;=============================================================================

ASPECT_PLACE:	dd ASPECT_RATIO		; 1.2
CONST13:	dw 13			; 000Dh			
CONST100:	dw CENTERY		; 0064h
CONST160:	dw CENTERX		; 00A0h
CONST1792:	dw 1792			; 0700h
CONST65536:	dd 65536		; 00010000h
randommul:	dd 134775813		; 08088405h
randomseed:	dd 4347			; 000010FBh
credits:
		db	 2, 80,-5
		db      -2,50,4,69,2,62,2,69,2,81,2,62,2,69,2,79,2,62,2,69,2
		db	81,2,62,2,69,2,79,2,81,2,0	; { pat 0,2,4,6,8 }
		db      -2,50,4,70,2,62,2,70,2,81,2,62,2,70,2,79,2,62,2,70,2
		db	82,2,62,2,70,2,79,2,82,2,0	; { pat 1,3,5,7,9 }
		db       0
		db      55,32,56,32			; { pat 10 }
		db      51,32,53,24,55,8                ; { pat 11 }
		db      57,32,50,32		 	; { pat 12 }
		db      60,48,58,8,57,8                 ; { pat 13 }
		db      55,64		   		; { pat 14 }
		db      -2,67,16,62,16,69,16,70,16,0	; { pat 15 }
		db      -2,70,16,69,16,62,16,65,16,0    ; { pat 16 }
		db       0
		db       4, 50,1,128,1,128              ;{ pat 0-3 }
		db      65,28,64,2,65,2,64,16,62,8,60,8 ;{ pat 4 }
		db      67,28,65,4,60,16,65,8,64,8      ;{ pat 5 }
		db      62,32,50,16,64,8,65,8           ;{ pat 6 }
		db      67,32,60,16,62,8,64,8           ;{ pat 7 }
		db      62,128		  		;{ pat 8,9 }
		db      67,128		  		;{ pat 10,11 }
		db     	67,16,64,16,66,16,64,8,66,8	;{ pat 12 }
		db     	72,48,70,16                 	;{ pat 13 }
		db     	67,32,55,32                 	;{ pat 14 }
		db     	-2,31,32,55,32,0                ;{ pat 15 }
		db      -2,26,32,50,32,0                ;{ pat 16 }
		db       0
		db       5, 89,-5,1,128,0		;{ pat 0-9 }
		db      67,8,74,24,68,8,75,24           ;{ pat 10 }
		db      63,8,70,24,60,8,69,16,67,8      ;{ pat 11 }
		db      62,8,69,16,67,8,62,8,66,24	;{ pat 12 }
		db      63,8,67,24,60,8,67,16,69,8	;{ pat 13 }
		db      55,8,67,24,43,8,50,24           ;{ pat 14 }
		db      -2,31,1,38,63,0                	;{ pat 15 }
		db      -2,26,1,33,63,0                	;{ pat 16 }
		db       0
		db	10,  0,-16,42,2,42,2,42,2,42,1,42,1,0 ;{ pat 0,1 }
		db     -16,36,2,42,2,42,2,42,1,42,1,0   ;{ pat 2,3 }
		db     -30,36,2,42,2,46,2,36,1,42,1,38,2
		db	42,2,46,2,38,1,42,1     	;{ pat 4-16 }
		db      36,2,38,2,36,2,42,1,42,1,38,2,42,2,46,2,38,1,42,1,0
		db     	 0
		db	 0

; colortable 65 bytes
colors 		db	16
                db      31,63,63,63
                db	 1, 0, 0, 0
                db      31,40,32,63
                db	 1, 0, 0, 0
                db      31,63, 0, 0
                db	 1, 6, 1, 0
                db      31,63,41,20
                db	 1, 0, 0, 0
                db      31,63,63, 8
                db	 1, 0, 0, 0
                db	31,56,56,63
                db	 1,63, 0, 0
                db      16,63,63, 0
                db      16,63, 0, 0
                db	 1,22, 5, 0
                db       7,63,56,17

; parameter for the texture effects 156 bytes
aE              db	013h,15,15,49,49,10
                db      013h,16,16,48,48,17
                db      013h,17,17,47,47,24
                db      013h,18,18,46,46,190
                db      013h,21,21,43,43,30
                db      025h,0,0,62,30,3
                db      025h,3,3,62,30,7
                db      025h,3,3,59,27,0FCh
                db      025h,0,32,62,62,3
                db      025h,3,35,62,62,7
                db      025h,3,35,59,59,0FCh
                db      025h,0,0,63,63,0FEh
                db      02Ch,0,10,63,15,0F6h
                db      02Ch,0,11,63,16,4
                db      02Ch,0,47,63,52,0F6h
                db      02Ch,0,48,63,53,4
                db      02Eh,19,24,44,39,5
                db      02Eh,20,25,44,39,0F4h
                db      02Eh,20,25,43,38,7
                db      03Eh,20,25,43,38,6
                db      02Fh,0,24,63,30,6
                db      02Fh,0,25,63,31,0FAh
                db      03Fh,0,25,63,30,6
                db      02Fh,0,32,63,38,6
                db      02Fh,0,33,63,39,0FAh
                db      03Fh,0,33,63,38,6

; parameter for fractaladd 28 bytes
aF:             db      34,192,38,1,38,1,38,0,32,0,32,32,32,64
                db	34,96,36,0,34,96,36,0,36,0,36,0,36,0

; star bob for the sparcling stars texture 25 bytes
bob:            db	0,0,3,0,0
                db	0,2,5,2,0
                db	3,5,7,5,3
                db	0,2,5,2,0
                db	0,0,3,0,0

cliptab:	db	4,4,12,4,8

uvtab:		db	0,0,63,63,63,0,0,63

cube:		db	1*8,5*8,6*8,2*8
                db      3*8,7*8,4*8,0*8
                db      2*8,6*8,7*8,3*8
                db      0*8,4*8,5*8,1*8
        	db	7*8,6*8,5*8,4*8
                db      0*8,1*8,2*8,3*8

print:		db	-32,-32,-32
                db       32,-32,-32
                db   	 32, 32,-32
                db  	-32, 32,-32
                db  	-32,-32, 32
                db       32,-32, 32
                db   	 32, 32, 32
                db  	-32, 32, 32
                db       64,  0,  0
                db      -64,  0,  0
                db        0, 64,  0
                db        0,-64,  0
                db        0,  0, 64
                db        0,  0,-64
                db	  0,  0,  0

; world contruction data 599 bytes
world:		db	071h,070h,000h,006h
                db	072h,000h,000h,006h
                db	071h,000h,070h,006h
                db	073h,007h,070h,006h
                db	073h,007h,000h,006h
                db	070h,007h,007h,006h
                db	074h,000h,007h,006h
                db	070h,000h,007h,040h
                db	072h,070h,007h,050h
                db	072h,070h,000h,050h
                db	071h,070h,070h,050h
                db	073h,000h,070h,040h
                db	071h,000h,000h,040h
                db	072h,000h,000h,050h
                db	071h,000h,070h,050h
                db	073h,007h,070h,046h
                db	073h,000h,000h,046h
                db	070h,007h,007h,046h
                db	072h,000h,007h,050h
                db	071h,000h,000h,000h
                db	071h,000h,000h,000h
                db	071h,000h,0BBh,056h
                db	070h,00Fh,0BBh,046h
                db	0FFh
                db	033h,000h,000h,000h
                db	0F0h,000h,007h,006h,0E4h
                db	0B0h,000h,0BBh,046h,0E4h
                db	090h,000h,0BBh,056h,0E4h
                db	090h,000h,0BBh,056h,0E4h
                db	030h,000h,0BBh,056h
                db	0F0h,000h,0BBh,056h,011h
                db	0F0h,000h,0BBh,046h,011h
                db	0B0h,000h,0BBh,056h,011h
                db	090h,000h,0BBh,056h,011h
                db	0B0h,000h,0BBh,056h,011h
                db	0F0h,000h,0BBh,056h,011h
                db	0F0h,000h,0BBh,046h,011h
                db	0B0h,000h,0BBh,056h,011h
                db	030h,000h,0BBh,056h
                db	010h,000h,0BBh,056h

                db	034h,000h,000h,000h
                db	032h,005h,000h,080h
                db	035h,005h,080h,080h
                db	035h,005h,080h,000h
                db	033h,005h,080h,008h
                db	033h,005h,000h,008h
                db	074h,005h,008h,008h
                db	074h,005h,000h,000h
                db	073h,005h,008h,080h
                db	075h,000h,000h,000h
                db	075h,005h,008h,088h
                db	070h,000h,000h,000h
                db	074h,064h,008h,008h
                db	074h,060h,008h,000h
                db	072h,064h,008h,080h
                db	005h,060h,000h,080h
                db	005h,060h,000h,000h
                db	002h,060h,000h,008h
                db	034h,060h,000h,008h
                db	034h,060h,000h,000h
                db	032h,060h,000h,080h
                db	035h,060h,000h,080h
                db	035h,060h,000h,000h
                db	032h,060h,000h,008h
                db	034h,035h,000h,008h
                db      014h,065h,000h,000h
                db      032h,035h,000h,080h
               	db      035h,035h,000h,080h
               	db      015h,065h,000h,000h
                db	032h,035h,000h,008h
                db	034h,035h,080h,008h
               	db      014h,065h,000h,000h
               	db      032h,035h,080h,080h
		db	075h,000h,000h,000h
		db	052h,065h,0E0h,077h
		db	032h,064h,00Eh,077h
		db	012h,065h,000h,077h
		db	000h,065h,000h,077h
		db	0FFh
		db	032h,000h,000h,000h
		db	0F0h,000h,000h,000h,014h
		db	0B0h,000h,000h,000h,014h
		db	030h,000h,000h,000h
		db	0F0h,000h,000h,000h,0F4h
		db	0F0h,000h,0DDh,056h,0F4h
		db	030h,000h,0DDh,046h
		db	030h,000h,0DDh,056h
		db	030h,000h,0DDh,056h
		db	032h,000h,000h,050h
		db	030h,00Ah,0A0h,050h
		db	033h,000h,0A0h,050h
		db	030h,000h,000h,050h
		db	032h,070h,000h,050h
		db	030h,000h,0A0h,050h
		db	033h,0A0h,0A7h,050h
		db	033h,000h,000h,000h
		db	031h,0A0h,07Ah,050h
		db	031h,000h,00Ah,050h
		db	031h,000h,00Ah,050h
		db	032h,00Ah,00Ah,050h
		db	035h,000h,000h,000h
		db	072h,00Ah,000h,000h
		db	070h,00Ah,0A0h,000h
		db	073h,000h,0A0h,000h
		db	070h,000h,000h,000h
		db	072h,000h,000h,000h
		db	070h,000h,0A0h,000h
		db	073h,0A0h,0A0h,000h
		db	073h,0A0h,000h,099h
		db	071h,0A0h,00Ah,000h
		db	071h,000h,00Ah,000h
                db	071h,000h,00Ah,000h
                db	075h,00Ah,00Ah,000h
                db	070h,00Ch,00Ch,003h
                db	070h,000h,00Ch,003h
                db	070h,000h,00Ch,003h
                db	072h,0C0h,07Ch,003h
                db	072h,000h,000h,000h
                db	071h,0C0h,0C7h,003h
                db	073h,000h,0C0h,003h
                db	071h,070h,000h,003h
                db	072h,000h,000h,003h
                db	071h,000h,0C0h,003h
                db	073h,00Ch,0C0h,003h
                db	071h,000h,000h,003h
                db	031h,00Ch,0CCh,0A3h
                db	0FFh
                db	032h,000h,000h,000h
                db	0F0h,000h,070h,006h,014h
                db	0B0h,000h,0DDh,046h,014h
                db	030h,000h,0DDh,056h
                db	0B2h,000h,00Dh,056h,0C4h
                db	032h,0DDh,000h,056h
                db	032h,0DDh,000h,056h
                db	032h,0DDh,000h,056h
                db	070h,000h,0F0h,056h
                db	070h,000h,0BBh,056h
                db	032h,0B0h,00Bh,046h
                db	072h,0BBh,000h,056h
                db	071h,0B0h,0B0h,056h
                db	071h,002h,011h,056h
                db	071h,022h,011h,056h
                db	031h,020h,011h,056h
                db	073h,00Bh,0B0h,056h
                db	073h,0BBh,000h,056h
                db	030h,00Bh,00Bh,046h
                db	030h,000h,0BBh,056h
                db	0FFh

; flying script	126 bytes
script:
;     7 6 5 4 3 2 1 0
;	  v v v v v c c c
;
;	  v = VALUE
;	  c = COMMAND
;
;	  0 = NOP
;	  1 = NEG ZSTEP
;	  2 = INC SPEED
;	  3 = DEC SPEED
;	  4 = INC XSTEP
;	  5 = DEC XSTEP
;	  6 = INC YSTEP
;	  7 = INC YSTEP

                db      0A1h,0f8h,0f8h,098h,0a1h,0A6h
                db      0F0h,0A7h,0B3h,037h,010h,036h
                db      050h,084h,085h,085h,084h,0F0h
                db      0F0h,0B2h,0A7h,0A6h,0A6h,0A7h
                db      0f3h,026h,070h,027h,080h,044h
                db      045h,077h,076h,0a6h,0b0h,061h
                db      061h,052h,0a7h,077h,030h,076h
                db      080h,0a2H,001h,041h,041h,001h
		db	0f5h,030h,0f4h,0b3h,0a4h,0f8h
		db	0a5h,0D0h,047h,046h,0F0h,0A6h
                db      080h,0A7h,070h,0A7h,010h,0A6h
                db      08eh,0f0h,050h,08fh,0b2h,0f8h
                db      0a3h,080h,08eh,0f0h,050h,08fh
                db      0b7h,010h,0b6h,0f0h,080h,0a6h
		db      0a7h,0f0h,087h,0F0h,070h,086h
		db      036h,0f0h,0f0h,090h,037h,083h
                db      02ch,0f0h,0f0h,0f0h,030h,02dh
		db	082h,030h,0b5h,0b4h,0f2h,0a6h
		db	030h,0a7h,083h,083h,0a6h,0f0h
		db	058h,0a7h,077h,076h,0f0h,0f0h
                db	0f0h,0f0h,0f8h,0f8h,000h

zstep:		dw	1			
doortimer	dw 	-4250	; 0EF66h
omniscent	db	"OMNISCENT"
omniend:
sanction        db      "(C) DIRK KPPERS"
sancend:
ob:		dd 	-330.0	; vector.x
		dd 	   0.0	; vector.y	
		dd	  64.0	; vector.z	
owmat:
		dd 	   0.0	; vector.x
		dd 	  -1.0	; vector.y
		dd	   0.0  ; vector.z
;owmat+12:
		dd 	   0.0	; vector.x
		dd 	   0.0	; vector.y
		dd	  -1.0  ; vector.z
;owmat+24:
		dd 	   1.0	; vector.x
		dd 	   0.0	; vector.y
		dd	   0.0  ; vector.z

bss_start:

ABSOLUTE bss_start

alignb 4

; 05/02/2017 (32 bit -> 16 bit)

;=============================================================================
;        	null-initialized data
;=============================================================================

nullstart:
wmat:           resb	matrix.size  ; 36
nwmat:		resb	matrix.size  ; 36
zspeed:		resw	1
oxw:		resw	1
oyw:		resw	1
ozw:		resw	1
scriptptr:	resw	1
scriptanz:	resw	1
scriptins:	resb	1
once:		resb	1
ticker:		resw	1
tracks:		resw	1
palette:        resb 	768
channels:       resb	16*6
;o:		resb	object.size ; 7204
; 10/02/2017
object.panz:	resw 1
object.fanz:	resw 1
object.p:	resb point.size*MAXPOINTS
object.f:	resb face.size*MAXFACES
nullend:

;=============================================================================
;       	uninitialized data
;=============================================================================
oldstack        resw	1
Old08IrqPtr:
Old08Irqofs:	resw	1
Old08Irqseg:	resw	1
;Old09IrqPtr:
;Old09Irqofs:	resw	1
;Old09Irqseg:	resw	1
;songdata:	resb	3605
root:   	resw	1
circletab:	resw	32
stars:		resb	90
twice:		resb	1
timer_event_number:	resb 1 ; 06/02/2017
vseg:		resw	1
bseg:		resw    1
tseg:   	resw	20
shadetab:	resb	256*128
p:		resw	4*15
pr:		resd	3*15
po:		resb	poly.size ; 5*36
rp:		resd	3*MAXPOINTS ; 3*400
facei:		resd    MAXFACES ; 400

alignb 4
es_:		resd    1 ; 16/01/2017
fs_:		resd	1 ; 16/01/2017

; 06/02/2017
cw.direc:	resw	1 ; word
cw.shade:	resw	1 ; word
;
dcf.d:		resw	1 ; word
dcf.h:		resw	1 ; word	
dcf.j:		resw	1 ; word
dcf.col:	resw	1 ; word
dcf.is_in:	resb	1 ; byte
		resb	1
dcf.p0:		resb	poly.size ; 5*36 bytes
dcf.p2:		resb	poly.size ; 5*36 bytes
;
sstp.edg:	resb	edges.size * 3 ; 60 bytes
sstp.del:	resb	edges.size * 3 ; 60 bytes 
sstp.mx1:	resw	1 ; word
sstp.mx2:	resw	1 ; word	 				
sstp.miny:	resw	1 ; word
sstp.maxy:	resw	1 ; word
sstp.y:		resw	1 ; word
sstp.l:		resw	1 ; word	 				
sstp.r:		resw	1 ; word
sstp.uu1:	resw	1 ; word
sstp.vv1:	resw	1 ; word
sstp.uu2:	resw	1 ; word	 				
sstp.vv2:	resw	1 ; word
sstp.ddu:	resw	1 ; word
sstp.ddv:	resw	1 ; word
sstp.dy:	resd	1 ; dword

alignb 4

bss_end: