; ****************************************************************************
; 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: 12/08/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 !

; 01/03/2017
; 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
_fpsave	equ 37
_pri	equ 38
_rele	equ 39
_fff	equ 40
_fnf	equ 41
_alloc	equ 42
_dalloc equ 43
_calbac equ 44	

[BITS 32] ; 80386 Protected Mode (32 bit) intructions

%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
;==============================================================================
;***********************************************
;* description	: 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

;***********************************************
;* description	: 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

;***********************************************
;* description	: 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

;***********************************************
;* description	: 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

;***********************************************
;* description	: 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
		; 12/08/2017
		mov	ecx ((bss_end-nullstart)+3)/4
		rep	stosd
%endmacro

;***********************************************
;* description	: 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

;***********************************************
;* description	: 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

;************************************************
;* description	: 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

;**************************************************
;* description	: 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

;***********************************************
;* description	: 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

;**************************************************
;* description	: create the reactor wall texture *
;* parameter	: none		               	  *
;* sideeffect	: ax,bx,cx,di,es               	  *
;* back		: none			       	  *
;* length	: 45 bytes		       	  * 
;**************************************************
%macro		reactorWall 0
		; 26/07/2017
		movzx	ebp, word [tseg]
		shl	ebp, 4
		mov	[_es], ebp
		xor	edi, edi
		mov	ecx, 4096 ; 1000h
rsmloop:
		mov	eax, edi
		test	al, 8
		jle	short rsnonot1
		not	al
rsnonot1:
		and	al, 15 ; 0Fh
		mov	ebx, eax
		mov	eax, edi
		shr	ax, 6
		test	al, 8
		jle	short rsnonot2
		not	al
rsnonot2:
		and	al, 15 ; 0Fh
		cmp	al, bl
		jle	short rstakeal
		mov	eax, ebx
rstakeal:
		add	al, 224 ; 0E0h
		add	edi, ebp
		stosb
		sub	edi, ebp
		loop	rsmloop
%endmacro

;***********************************************
;* description	: calc background-fractal      *
;* parameter	: none		               *
;* sideeffect	: ax,bx,cx,si,di,es	       *
;* back		: none			       *
;***********************************************
%macro		createFrac2 0
		; 12/08/2017
		; 26/07/2017
		movzx	ebp, word [tseg+36]
		shl	ebp, 4
		mov	[_es], ebp
		mov	al, 20	; 14h
		call	setFrac
		mov	edi, 64
		;mov	ecx, 4096-64 ; 0FC0h
		mov	cx, 4096-64
		mov	ebx, 4  ; 16/12/2016
cF1loop:
		;mov	bx, 4
		call	rnd
		; 12/08/2017
		;add	edi, ebp
		;add	al, [edi-64]  ; byte [es:di-64]
		;add	al, [edi-63]  ; byte [es:di-63]
		add	al, [ebp+edi-64]
		add	al, [ebp+edi-63]
		dec	ax
		shr	ax, 1
		;stosb
		;sub	edi, ebp
		mov	[ebp+edi], al
		inc	edi
		loop	cF1loop
%endmacro

;***********************************************
;* description	: calc random noise fractal    *
;* parameter	: none		               *
;* sideeffect	: ax,bx,cx,si,di,es	       *
;* back		: none			       *
;***********************************************
%macro		createFrac3 0
		; 26/07/2017
		movzx	ebp, word [tseg+38]
		shl	ebp, 4
		mov	[_es], ebp
		mov	al, 3
		call	setFrac
		;mov	ecx, 4096
		mov	cx, 4096 ; 1000h
		mov	ebx, ecx
cF3loop:
		;mov	bx, 4096 ; 1000h
		call	rnd
		movzx	edi, ax
		inc	byte [ebp+edi]
		loop	cF3loop
%endmacro

;**************************************************
;* description	: init stars (positions and state)*
;* parameter	: none			          *
;* sideeffect	: eax,bx,cx,edx,si,di,es	  *
;* back		: none		                  *
;**************************************************
%macro		initStars 0
		; 26/07/2017
		;mov	cx, 30 ; 1Eh
		;mov	ecx, 30 ;
		mov	cl, 30
		mov	edi, stars
		xor	ebx, ebx
		mov	[_es], ebx ; 0
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

;***********************************************
;* description	: add effects to fractals      *
;* parameter	: none		               *
;* sideeffect	: ax,bx,cx,di,es	       *
;* back		: none		               *
;***********************************************
%macro		effects 0
		; 26/07/2017
		; effects
		;mov	cx, 26 ; 1Ah
		;mov	ecx, 26 ;
		mov	cl, 26
		mov	esi, aE
		;mov	si, aE
		xor	ebx, ebx
		xor	edi, edi
effmloop:
		push	ecx
		mov	bl, [esi]	; mseg+effect
		mov	dl, bl
		shr	dl, 4
		and	bl, 0Fh ; 15
		; 11/02/2017
		shl	bl, 1
		; 26/07/2017
		movzx	ebp, word [ebx+tseg]
		shl	ebp, 4
		mov	[_es], ebp
		;
		movzx	ecx, byte [esi+2] ; y1
effyloop:
		movzx	ebx, byte [esi+1] ; x1
effxloop:
		mov	edi, ecx
		shl	di, 6
		;add	di, bx
		add	edi, ebx
		mov	al, dl
		dec	al
		jz	short effect1
		dec	al
		jz	short effect2
		;mov	ax, bx
		mov	eax, ebx
		;add	ax, cx
		add	eax, ecx
		and	al, 4
		;jz	short effdonot
		jz	short effect1
		mov	al, 152 ; 98h
effdonot:
		jmp	short effect1
effect2:
		mov	al, [ebp+edi]	; 16/12/2016
effect1:
		add	al, [esi+5]	; value
		mov	[ebp+edi], al	; 16/12/2016
		inc	bl
		cmp	bl, [esi+3] 	; x2
		jle	short effxloop
		;inc	cx
		inc	cl
		cmp	cl, [esi+4]	; y2
		jle	short effyloop
		add	si, 6
		pop	ecx
		loop	effmloop
%endmacro

;***********************************************
;* description	: copy fractals and add value  *
;* parameter	: none		               *
;* sideeffect	: al,cx,di,es,fs	       *
;* back		: none		               *
;***********************************************
%macro		addFractals 0
		; 26/07/2017
		;mov	si, aF
		mov	esi, aF
		mov	dl, 4
aFloop:
		movzx	ebx, dl
		movzx	ebp, word [ebx+tseg] ; es:
		shl	ebp, 4
		mov	[_es], ebp
		xor	edi, edi
		lodsw
		mov	bl, al 
		;
		movzx	ebp, word [ebx+tseg] ; fs:
		shl	ebp, 4
		mov	[_fs], ebp
		;
		mov	cx, 4096 ; 1000h
		;mov	ecx, 4096 ;
		mov	ebx, [_es]
aFiloop:
		mov	al, [ebp+edi]  ; [fs:di]
		add	al, ah
		;stosb
		mov	[ebx+edi], al
		inc	edi
		loop	aFiloop
		;
		inc	dl
		inc	dl
		cmp	dl, 30
		jle	short aFloop
%endmacro

;***************************************************
;* description	: calculate and initalize textures *
;* parameter	: none			       	   *
;* sideeffect	: al,cx,di,es,fs		   *
;* back		: none			       	   *
;***************************************************
%macro		addLava 0
		; 28/07/2017
		; 26/07/2017
		movzx	ebp, word [tseg+22]
		shl	ebp, 4
		mov	[_es], ebp
		;
		mov	edi, 4095	; 0FFFh
		;mov	cx, 20		; 14h
		;mov	ecx, 20 ;
		mov	cl, 20
		;mov	al, 94		; 5Eh
		mov	eax, 94
aLyloop:
		push	ecx
		shl	cx, 3
aLxloop:
		push	edi
		push	eax
		;mov	bx, 64		; 40h
		mov	ebx, 64
		call	rnd
		sub	di, ax
		;sub	edi, eax
		pop	eax
		mov	[ebp+edi], al ; 17/01/2017
		pop	edi
		loop	aLxloop
		pop	ecx
		dec	al
		sub	di, 64 		; 40h
		loop	aLyloop
%endmacro

;***************************************************
;* description	: calculate and initalize textures *
;* parameter	: none		                   *
;* sideeffect	: al,cx,di,es,fs		   *
;* back		: none		                   *
;***************************************************
%macro		initTextures 0
		; 26/07/2017
		;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

;**************************************************
;* description	: cycle "range" colors at "base"  *
;* parameter	: none		                  *
;* sideeffect	: ax,(bl),cx,si,di,es             *
;* back		: none			          *
;**************************************************
%macro		colorCycle 0
		; 26/07/2017

		base	equ 6*32
                range	equ 32

		mov	dword [_es], 0 ; es = ds
		
		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

;***********************************************
;* description	: animate the stars	       *
;* parameter	: none			       *
;* sideeffect	: ax,bx,cx,dl,si,di,es	       *
;* back		: none			       *
;***********************************************
%macro		animStars 0
		; 26/07/2017

		_base	equ 7*32

		movzx	ebp, word [tseg+2]
		shl	ebp, 4
		mov	[_es], ebp

		call	clearFrac

		;mov	ecx, 30
		mov	cl, 30	; 1Eh
		
		;mov	bx, stars
		mov	ebx, 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]

		push	ecx
		push	ebx

		mov	edx, 64-5 ; 3Bh
		mov	cx, _base*256+0 ; 0E000h
		; 26/07/2017
		;ebp = [_es]
		call	setstarbob

		pop	ebx
		pop	ecx

		add	bx, 3
		loop	aSoloop
%endmacro

;***********************************************
;* description	: calculate shading tab	       *
;* parameter	: none		               *
;* sideeffect	: ax,bl,cx,di,es               *
;* back		: none		               *
;***********************************************
%macro		calcShadeTab 0
		; 26/07/2017
		mov	dword [_es], 0 ; es = ds

		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

;***********************************************
;* description	: 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

;***************************************************
;* description	: parse the script,rotate and move *
;* parameter	: none                	           *
;* sideeffect	: all		                   *
;* back		: none		                   *
;***************************************************
%macro		scriptIt 0
		; 11/08/2017

 		; 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
		; 11/08/2017 (16 bits pushes)
		;xor	eax, eax
sIpushloop:
		lodsw			      ; oxw, oyw, ozw	
		sar	ax, 2
		push	ax ; 16 bits push !! (esp = esp - 2)
		loop	sIpushloop

		imul	ax, word [si-4], 16   ; [oyw]*16 	

		push	ax ; 16 bits push !! (esp = esp - 2)

		; [esp] = [oyw]*16 ; angle or YSTEP * 16 ?		        	
		; [esp+2] = [ozw] ; ZSTEP
		; [esp+4] = [oyw] ; YSTEP
		; [esp+6] = [oxw] ; XSTEP

		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
		dec	ecx ; 26/07/2017
		jnz	sImloop
sItickerNull:
%endmacro

;**************************************************
;* description	: rotate all points from o -> rp  *
;* parameter	: none                	          *
;* sideeffect	: all		                  *
;* back		: none		                  *
;**************************************************
%macro		rotation 0
		; 26/07/2017
		;;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

;***********************************************
;* description	: sort faces by z-koord	       *
;* parameter	: none		               *
;* sideeffect	: ax,bx,cx,dx,si,di,es         *
;* back		: none		               *
;***********************************************
%macro		sortFaces 0
		; 26/07/2017
		mov	dword [_es], 0 ; es = ds

		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

;***********************************************
;* description	: animate the door  	       *
;* parameter	: none		               *
;* sideeffect	: ax,cx,si,di,es               *
;* back		: none		               *
;***********************************************
%macro		animDoor 0
		; 12/08/2017
		; 26/07/2017
		;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	eax
		starbackground
		pop	eax
alreadydrawed:
		cmp	ax, 24
		jle	short aDnoover
		mov	ax, 24
aDnoover:
		shl	ax, 6
		; 26/07/2017
		;push	dword [_ds]
		movzx	ebp, word [tseg+26]
		shl	ebp, 4
		mov	[_es], ebp
		movzx	ebx, word [tseg+30]
		shl	ebx, 4
		mov	[_ds], ebx
		mov	esi, ebx
		;add	si, ax ; 16/01/2017
		add	esi, eax
		mov	edi, ebp
		;mov	cx, 1024
		mov	ecx, 1024
		rep movsw
		mov	esi, 2048
		sub	si, ax
		push	esi
		add	esi, ebx ; 12/08/2017 
		mov	ch, 4  ; cx = 1024
		rep movsw
		pop	edi
		add	edi, ebp
		mov	cx, ax
		xor	eax, eax ; 0
		rep stosw
		;pop	dword [_ds]
		mov	[_ds], eax ; ds = cs
%endmacro

;***********************************************
;* description	: 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

;***********************************************
;* description	: 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

;***********************************************
;* description	: clear starbackground         *
;* parameter	: none		               *
;* sideeffect	: ax,es,di,cx,dx               *
;* back		: none		               *
;***********************************************
%macro		cls 0
		; 26/07/2017
		movzx	edi, word [bseg]
		shl	edi, 4
		mov	[_es], edi 
		;
		mov	esi, 0A0000h + (320*5) ; 0A0640h
		;mov	cx, 32000 ; 7D00h
		mov	ecx, 32000 ;
clsloop:
		lodsb
		stosb
		stosb
		loop	clsloop
%endmacro

;***********************************************
;* description	: draw starbackground	       *
;* parameter	: none		               *
;* sideeffect	: ax,es,di,cx,dx	       *
;* back		: none		               *
;***********************************************
%macro		starbackground 0
		; 26/07/2017
		movzx	ebp, word [bseg]
		shl	ebp, 4
		mov	[_es], ebp

		;mov	cx, 100 ; 64h
		mov	ecx, 100
starbackloop:
		push	ecx
		mov	bx, 320*155 ; 0C1C0h
		;mov	ebx, 320*155
		call	rnd
		add	ax, 320*20  ; 1900h
		; 05/02/2017
		movzx	edi, ax
		and	ah, 7
		;mov	dx, 320-5   ; 13Bh
		mov	edx, 320-5 ; ?? 
		mov	cx, 2
		; 26/07/2017
		;ebp = [_es]
		call	setstarbob
		pop	ecx
		loop	starbackloop
%endmacro

;***********************************************
;* description	: create identity matrix       *
;* parameter	: ds:di address                *
;* sideeffect	: cx,di		   	       *
;* back		: none			       *
;***********************************************
%macro		identityMat 0
		; 11/08/2017
		; nwmat:
		; dd 1,0,0,0,1,0,0,0,1 
		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
		add	edi, 4 ; 26/07/2017
		dec	cl
		jns	short iMilp
		dec	ch
		jns	short iMolp
%endmacro

;=============================================================================
;               entry point
;=============================================================================
;***********************************************
;* description	: entry point		       *
;* parameter	: none		               *
;* sideeffect	: all		               *
;* back		: none		               *
;***********************************************

[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

			; 26/07/2017
		;mov	edi, vseg ;
		mov	di, vseg
		mov	ax, 1000h
		stosw	; vseg		; virtual screen address
		add	ax, 1000h
		stosw	; bseg		; star background address
		add	ax, 1000h
		mov	cx, 20
segloop:				; texture addresses
		stosw	; tseg +
		;add	ax, 100h
		inc	ah
		loop	segloop

		; 09/04/2017
		sub	eax, eax
		mov	edi, 10000h
		mov	ecx, (65536+65536+(20*4096))/4
		rep	stosd 

		; 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	[oldstack], esp

		startTimer
		startKBDHandler
		cls
mainloop:
		; 12/08/2017
		cmp	byte [tstatus], 0
		ja	_check_kbdb

		mov	byte [tstatus], 1

		; 26/07/2017
		;mov	ah, 1	; Check keyboard buffer
		;;int	16h	; Keyboard interrupt
		;int	32h	; TRDOS 386 - Jeyboard interrupt
		;jnz	_exit_  ; exit

		setPalette2

		scriptIt
	
		animDoor

		; 26/07/2017
		movzx	edi, word [vseg]  ; es = [vseg]
		shl	edi, 4
		mov	[_es], edi
		movzx	esi, word [bseg]  ; ds = [bseg]
		shl	esi, 4
		mov	[_ds], esi
		call	copyseg
		mov	dword [_ds], 0 ; ds = cs

		rotation
		sortFaces

		;movzx	ecx, word [o+object.fanz]
		movzx	ecx, word [object.fanz]

		mov	esi, facei
drawloop:
		; 27/07/2017
		lodsw
		lodsw
		;movzx	ebx, ax ; face address in 'o+object.f'
		movzx	ebx, ax ; face address in 'object.f'
		;pushad
		push	esi
		push	ecx
		call	drawclippedface
		pop	ecx
		pop	esi
		;popad
		loop	drawloop

		movzx	esi, word [vseg] ; ds = [vseg]
		shl	esi, 4
		mov	[_ds], esi

		mov	edi, 0A0000h
		mov	[_es], edi ; es = 0A000h

		call	copyseg

		mov	dword [_ds], 0 ; ds = cs ; 11/08/2017

_check_kbdb:
		mov	ah, 1	; Check keyboard buffer
		int	32h	; TRDOS 386 Keyboard interrupt
		;jnz	_exit_  ; exit
		;jmp	mainloop
		jz	mainloop ; 11/02/2017
loc_err_exit:
_exit_:
		; 26/07/2017
		mov	dword [_ds], 0  ; ds = cs
		mov	esp, [oldstack]
		silence
		stopKBDHandler
		stopTimer
;restore_text_mode:
		set80x25
terminate:
		sys 	_exit   ; INT 40h
here:
		jmp	short here

;==============================================================================
;		interrupt handler
;==============================================================================
;***********************************************
;* description	: timer routine		       *
;* parameter	: none		               *
;* sideeffect	: none		               *
;* back		: none		               *
;***********************************************

timer_callback:
		; 12/08/2017
		; 10/08/2017
		
		playsong

		inc	word [ticker]
		inc	byte [twice]
		
		; 12/08/2017
		;and	byte [twice], 7
		;jnz	short tr_1

		; 12/08/2017 
		; (25 Hz is necessary for proper rendering...)
		; (50 Hz was enough for DOS real mode
		; but not enough for TRDOS 386 protected
		; mode, for real computer and Virtual Box running.)

		and	byte [twice], 15 ; 23.333 Hz  (350/15)
		jnz	short tr_1

		mov	byte [tstatus], 0 ; screen update (50 Hz) flag
		
		colorCycle
		animStars

		;inc	word [doortimer]
tr_1:
		; 12/08/2017
		; (25 Hz is not ennough for final StarBackground)
		
		test byte [twice], 7 ; 50 Hz
		jnz	short tr_2

		inc	word [doortimer] ; (animDoor, starbackground)
tr_2:
		mov	eax, 39	; 'sysrele'
		int	40h	; TRDOS 386 system call
	
;==============================================================================
;		sub routines
;==============================================================================
;***********************************************
;* description	: draw a the starbob	       *
;* parameter	: ds,es: source seg,dest seg   *
;* sideeffect	: ax,cx,si,di	               *
;* back		: none		               *
;***********************************************

setstarbob:
		; 26/07/2017
		;mov	ebp, [_es]
		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	[ebp+edi], al  ; mov [es:di], al
aSnodraw:
		;inc	di
		inc	edi
		dec	bh
		jnz	short xloop
		add	di, dx
		dec	bl
		jnz	short yloop
		retn

;***********************************************
;* description	: 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

;***********************************************
;* description	: expand a part of the song    *
;* parameter	: si:base adress	       *
;* sideeffect   : si,ax		               *
;* back		: ax=si:new baseadress	       *
;***********************************************

expand:
EPwhile: 	mov	cl, [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

;**************************************************
;* description	: recursive index quicksort       *
;* parameter	: l,r:stack left and right border *
;* sideeffect	: ax,bx,cx,dx,si,di               *
;* back		: none		                  *
;**************************************************

qsort:		
		; 11/08/2017
		; 07/04/2017
 		; 10/02/2017
 		; 29/01/2017

		pop	eax 	; get return address
		pop	ecx	; get 2. param r
		pop	ebx	; get 1. param l
		push	eax	; store return address

		cmp	ecx, ebx
		jle	short QSendrek
		mov	esi, ebx
		mov	edi, ecx  	
		mov	dx, [esi]
		jmp	short QSwhile2
QSrepeat:
QSwhile1:	cmp	[esi], dx
		jle	short QSwhile2
		add	esi, 4
		jmp	short QSwhile1
QSwhile2:
		cmp	[edi], dx
		jnl	short QSwhile2e
		sub	edi, 4
		jmp	short QSwhile2
QSwhile2e:
		cmp	esi, edi
		;jg	short QSnoswap
		jg	short _QSnoswap
		lodsd
		xchg	eax, [edi]
		mov	[esi-4], eax
		sub	edi, 4
QSnoswap:
		cmp	esi, edi
		jle	short QSrepeat
_QSnoswap:
		push	esi 
		push	ecx
		push	ebx
		push	edi
		call	qsort
		call	qsort
QSendrek:
		retn

;*************************************************
;* description	: 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

;************************************************
;* description	: 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

;***********************************************
;* description	: send a byte to the GM-Port   *
;* parameter	: al:midi command              *
;* sideeffect	: dx		               *
;* back		: none		               *
;***********************************************

writeGM:
		mov	dx, GMPort  ; 331h
		push	ecx
		push	eax
		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+8j
		pop	eax
		pop	ecx
		dec	dx
		;out	dx, al
		
		mov	ah, 1	; out (byte)
  		int	34h	; TRDOS 386 - IOCTL interrupt

		retn

;**************************************************
;* description	: 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

;***********************************************
;* description	: send CHANGEPRG command       *
;* parameter	: al:channel;ah:instrument     *
;* sideeffect	: dx,al		               *
;* back		: none		               *
;***********************************************

setinstr:
		call	writeGM
		mov	al, ah
		call	writeGM
		retn

;**************************************************
;* description	: clear/set the fractal es: to al *
;* parameter	: al,es		                  *
;* sideeffect	: ax,cx,di,es  	                  *
;* back		: none			          *
;**************************************************

clearFrac:
		xor	eax, eax
setFrac:
		; 26/07/2017
		;xor	di, di
		mov	edi, [_es]
		;mov	cx, 4096 ; 1000h
		mov	ecx, 4096
		rep stosb
		retn

;***********************************************
;* description	: calc shade bob fractal       *
;* parameter	: es:seg;num,rad:stack         *
;* sideeffect	: all			       *
;* back		: none			       *
;***********************************************

createFrac1:
		; 26/07/2017

		;; *mov	 ebx, 34
		;; *push 800	 ; 320h ; arg 2
		;; *push 5		; arg 1 	
		;; *call createFrac1
		;; *mov	 ebx, 32 ; 20h
		;; *push 112	 ; 70h  ; arg 2
		;; *push 15	 ; 0Fh  ; arg 1
		;; *call createFrac1

		rad	equ 8  ; arg 1 in [esp+4]
		num	equ 12 ; arg 2 in [esp+8]

		push	ebp
		mov	ebp, esp
		;
		;movzx	ebx, word [ebx+tseg] ; es:
		mov	bx, [ebx+tseg]
		shl	ebx, 4
		mov	[_es], ebx
		call	clearFrac
		;mov	si, circletab
		mov	esi, circletab
		;mov	dx, [ebp+rad]
		mov	edx, [ebp+rad]		
		;movzx	eax, dl
		;mov	eax, edx
		mov	al, dl
		imul	dl
		;mov	di, ax
		;mov	bx, ax
		mov	ebx, eax
		;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	[esi], ax
		fild	word [esi]
		fsqrt
		fistp	word [esi]
		inc	esi
		inc	esi
		dec	dx
		loop	CCTloop

		mov	cx, [ebp+num]
SBloop1:
		push	ecx
		;mov	ebx, 4096 ; 1000h
		mov	bx, 4096
		call	rnd
		movzx	edi, ax ; 05/02/2017
		;mov	esi, circletab
		mov	si, circletab
		mov	cx, [ebp+rad]
		;add	cx, cx
		add	ecx, ecx
		mov	ebx, [_es]
SBloop2:
		push	ecx
		lodsw
		mov	cx, ax
		;add	cx, cx
		add	ecx, ecx
		jz	short SBskip
		push	edi
		sub	di, ax
SBloop3:
		and	di, 4095  ; 0FFFh
		inc	byte [ebx+edi] ; 17/01/2017
		;inc	di
		inc	edi
		loop	SBloop3
		pop	edi
SBskip:
		add	di, 64 ; 40h
		pop	ecx
		loop	SBloop2
		pop	ecx
		loop	SBloop1
		pop	ebp
		ret	8

;**************************************************
;* description	: 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:
		; 12/08/2017
		; 10/08/2017
		; 26/07/2017
		; 07/04/2017
		; 30/01/2017

		;; *mov   edi, dcf.p2
		;; *push  edi		 ; arg 3 ; 32 bits push !
		;; *push  word [dcf.j]   ; arg 2 ; 16 bits push !!
		;; *push  word [dcf.col] ; arg 1 ; 16 bits push !!
		;; *call  scansubtextpoly

		; 10/08/2017 (operand size bugfix, 8, 10, 12)
		col	equ 8   ; arg 1, [esp+4]  ; dcf.col value
		n	equ 10  ; arg 2, [esp+6]  ; dcf.j value
		pol	equ 12  ; arg 3, [esp+8]  ; dcf.p2 address

		; 12/08/2017
		;enter	150, 0	; 96h
		enter	152, 0  ; 98h		
			; push ebp ; mov ebp, esp ; sub esp, 152

		; ebp - x
		sstp.edg  equ -60   ; 90-150 ; edges * 3
		sstp.del  equ -120  ; 30-150 ; edges * 3 
		sstp.mx1  equ -122  ; 28-150 ; word
		sstp.mx2  equ -124  ; 26-150 ; word	 				
		sstp.miny equ -126  ; 24-150 ; word
		sstp.maxy equ -128  ; 22-150 ; word	
		sstp.y	  equ -130  ; 20-150 ; word
		sstp.l	  equ -132  ; 18-150 ; word	 				
		sstp.r	  equ -134  ; 16-150 ; word
		sstp.uu1  equ -136  ; 14-150 ; word
		sstp.vv1  equ -138  ; 12-150 ; word
		sstp.uu2  equ -140  ; 10-150 ; word	 				
		sstp.vv2  equ -142  ;  8-150 ; word
		sstp.ddu  equ -144  ;  6-150 ; word
		sstp.ddv  equ -146  ;  4-150 ; word
		;sstp.dy  equ -150  ;  0-150 ; dword
		sstp.dy   equ -152  ;  0-152 ; dword
		; 

		; 21/01/2017
		mov	eax, 32767
		mov	edx, eax
		mov	ebx, eax
		neg	bx	 ; -32767 ; 8001h
		mov	esi, ebx ; -32767
		
		;e di = 32 bit address (in stack) /// 18/01/2017		
		mov	edi, [ebp+pol] ; [ebp+12] ; dcf.p2 ; face structure

		xor	ecx, ecx
minmax:
		cmp	ax, [edi+2+edge.e+edges.x] ; [edi+12h]
		jle	short noswap1
		mov	ax, [edi+2+edge.e+edges.x] ; [edi+12h]
noswap1:
		cmp	bx, [edi+2+edge.e+edges.x] ; [edi+12h]
		jge	short noswap2
		mov	bx, [edi+2+edge.e+edges.x] ; [edi+12h]
noswap2:
		cmp	dx, [edi+edge.py]  ; [edi+0Ch]
		jle	short noswap3
		mov	dx, [edi+edge.py]  ; [edi+0Ch]
		mov	[ebp+sstp.l], cx
		mov	[ebp+sstp.r], cx
noswap3:
		cmp	si, [edi+edge.py]  ; [edi+0Ch]
		jge	short noswap4
		mov	si, [edi+edge.py]  ; [edi+0Ch]
noswap4:
		add	di, 36 ; 24h
		;inc	cx
		; 10/08/2017
		inc	ecx
		cmp	cx, [ebp+n] ; [ebp+10]
				    ; 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	[ebp+sstp.miny], dx
		mov	[ebp+sstp.maxy], si

		;{ down clipping }
		cmp	word [ebp+sstp.maxy], YMAX ; 0B3h
		jle	short noclipdown
		mov	word [ebp+sstp.maxy], YMAX ; 0B3h
noclipdown:
		mov	ax, [ebp+sstp.miny]
		cmp	ax, [ebp+sstp.maxy]
		je	exitDraw
		mov	[ebp+sstp.y], ax
		; 05/02/2017
		;mov	ebx, [ebp+col]	; [ebp+8]
					 ; dcf.col ; shade/color index
		mov	bx, [ebp+col] ; 07/04/2017
		; 26/07/2017
		add	bx, bx ; shl bx, 1
		;movzx	eax, word [vseg]
		mov	ax, [vseg] ; es = [vseg]
		shl	eax, 4
		mov	[_es], eax
		movzx	eax, word [ebx+tseg] ; fs = [ebx+tseg]
		shl	eax, 4
		mov	[_fs], eax
for:
		movzx	eax, word [ebp+sstp.y]
		cmp	ax, word [ebp+sstp.maxy]
		jg	exitDraw
		je	exitwhile2
while1:
		;mov	ax, [ebp+sstp.y]
		;cmp	ax, [ebp+sstp.maxy]
		;jge	short while2	
		; 05/02/2017
		imul	bx, word [ebp+sstp.l], 36
		movzx	esi, bx
		add	esi, [ebp+pol]	; [ebp+12]

		cmp	ax, [esi+edge.py] ; [esi+0Ch]
		jne	short while2

		mov	bx, [ebp+sstp.l]
		dec	bx
		jge	short nounder
		mov	bx, [ebp+n]	; [ebp+10]
				 	; dcf.j ; visible edges/points
		dec	bx
nounder:
		mov	[ebp+sstp.l], bx
		xor	edi, edi
		call	calcDeltas
		mov	ax, [ebp+sstp.y]
		cmp	ax, [ebp+sstp.maxy]
		jge	short exitwhile2	
		jmp	short while1
while2:
		;mov	ax, [ebp+sstp.y]
		cmp	ax, [ebp+sstp.maxy]
		jge	short exitwhile2
		; 05/02/2017
		imul	bx, word [ebp+sstp.r], 36
		movzx	esi, bx
		add	esi, [ebp+pol]	; [ebp+12]

		cmp	ax, [esi+edge.py] ; [esi+0Ch]
		jne	short exitwhile2

		mov	bx, [ebp+sstp.r]
		inc	bx
		cmp	bx, [ebp+n]	; [ebp+10]
		jl	short noover
		;xor	bx, bx
		xor	ebx, ebx
noover:
		mov	[ebp+sstp.r], bx
		mov	edi, 20  ; 14h
		call	calcDeltas
		;
		mov	ax, [ebp+sstp.y]
		jmp	short while2
exitwhile2:
		;{ up clipping }
		cmp	word [ebp+sstp.y], YMIN	; 15h
		jl	clipup
		movzx	ebx, word [ebp+sstp.edg+2+edges.x]
		mov	[ebp+sstp.mx1], bx 
		movzx	ecx, word [ebp+sstp.edg+20+2+edges.x]
		mov	[ebp+sstp.mx2], cx
		sub	cx, bx
		jz	exitol
		cmp	word [ebp+sstp.mx2], 0
		jle	exitol
		cmp	word [ebp+sstp.mx1], XMAX ; 140h
		jg	exitol

		neg	bx
		jns	short myelse
		xor	bx, bx
		jmp	short myendif
_nodivbyzero:
		mov	eax, [ebp+edi+sstp.del+40]
		jmp	short nodivbyzero
myelse:
		mov	word [ebp+sstp.mx1], 0
myendif:
		mov	edi, 16 ; 10h
addloop1:
		;{ calculate deltas }
		mov	eax, [ebp+edi+sstp.edg+20]
		sub	eax, [ebp+edi+sstp.edg]
		cdq
		;jcxz	nodivbyzero
		jcxz	_nodivbyzero
		idiv	ecx
		mov	[ebp+edi+sstp.del+40], eax
nodivbyzero:
		;{ left clipping }
		mov	eax, [ebp+edi+sstp.del+40]
		imul	ebx
		add	eax, [ebp+edi+sstp.edg]
		mov	[ebp+edi+sstp.edg+40], eax
		sub	di, 4
		jnz	short addloop1

		mov	ax, [ebp+sstp.del+40+16]
		mov	[dels_pos_w], ax

		;{ right clipping }
		cmp	word  [ebp+sstp.mx2], XMAX
		jle	short norightclip
		mov	word  [ebp+sstp.mx2], XMAX
norightclip:
		imul	di, word [ebp+sstp.y], 320
		add	di, [ebp+sstp.mx1]
		
		mov	bx, 256 ; 100h
		mov	eax, [ebp+sstp.edg+40+edges.u]
		imul	ebx
		idiv	dword [ebp+sstp.edg+40+edges.w]
		mov	[ebp+sstp.uu2], ax
		mov	eax, [ebp+sstp.edg+40+edges.v]
		imul	ebx
		idiv	dword [ebp+sstp.edg+40+edges.w]
		mov	[ebp+sstp.vv2], ax
outloop:
		mov	cx, [ebp+sstp.mx2]
		sub	cx, [ebp+sstp.mx1]
		jle	exitol
		cmp	cx, SUBRANGE ; 10h
		jle	short lastSeg
		mov	cx, SUBRANGE ; 10h
lastSeg:
		;{ uu1:=uu2 }
		;{ vv1:=vv2 }
		mov	eax, [ebp+sstp.vv2]
		mov	[ebp+sstp.vv1], eax

		mov	eax, [ebp+sstp.del+40+edges.u]
		imul	ecx
		add	[ebp+sstp.edg+40+edges.u], eax
		mov	eax, [ebp+sstp.del+40+edges.v]
		imul	ecx
		add	[ebp+sstp.edg+40+edges.v], eax
		mov	eax, [ebp+sstp.del+40+edges.w]
		imul	ecx
		add	[ebp+sstp.edg+40+edges.w], eax

		mov	bx, 256 ; 100h
		mov	eax, [ebp+sstp.edg+40+edges.u]
		imul	ebx
		idiv	dword [ebp+sstp.edg+40+edges.w]
		mov	[ebp+sstp.uu2], ax
		mov	eax, [ebp+sstp.edg+40+edges.v]
		imul	ebx
		idiv	dword [ebp+sstp.edg+40+edges.w]
		mov	[ebp+sstp.vv2], ax

		mov	ax, [ebp+sstp.uu2]
		sub	ax, [ebp+sstp.uu1]
		cwd
		idiv	cx
		mov	[ddu_pos_w], ax

		mov	ax, [ebp+sstp.vv2]
		sub	ax, [ebp+sstp.vv1]
		cwd
		idiv	cx
		mov	[ddv_pos_w], ax

		mov	si, [ebp+sstp.vv1]
		mov	dx, [ebp+sstp.uu1]
		mov	ax, [ebp+sstp.edg+40+16]
innerloop:
 		; 05/02/2017
		movzx	ebx, si
		xor	bl, bl
		shr	bx, 2
		add	bl, dh
		add	ebx, [_fs]
		movzx	ebx, byte [ebx] ; [fs:bx]
		or	bl, bl
		jz	short dels_pos
		mov	bh, ah
		mov	bl, [ebx+shadetab]

		push	esi
		movzx	esi, di
		add	esi, [_es]
		mov	[esi], bl	; [es:di] 
		pop	esi
dels_pos:	
		add	ax, [dels_pos_w] ;{word ptr dels}
ddu_pos:	
		add	dx, [ddu_pos_w]  ;{word ptr ddu }
ddv_pos:	
		add	si, [ddv_pos_w]  ;{word ptr ddv }

		inc	di	
		loop	innerloop

		mov	[ebp+sstp.edg+40+16], ax
		add	word [ebp+sstp.mx1], SUBRANGE
		jmp	outloop
exitol:
clipup:		mov	edi, 36 ; 24h
addloop:
		mov	eax, [ebp+edi+sstp.del]
		add	[ebp+edi+sstp.edg], eax
		sub	di, 4
		jns	short addloop
		inc	word [ebp+sstp.y]
		jmp	for
exitDraw:
		; 12/08/2017
		leave
			; mov esp, ebp ; pop ebp
		; 10/08/2017
		ret	8 ; word, word, dword

;***************************************************
;* description	: calc deltas for vertical interp. *
;* parameter	: none			           *
;* sideeffect	: all		 	           *
;***************************************************

calcDeltas:
		; 12/08/2017
		; 26/07/2017
		imul	dx, bx,	36
		mov	ebx, esi
		movzx	esi, dx
		add	esi, [ebp+pol]  ; [ebp+12]
		;
		mov	ax, [esi+12]
		sub	ax, [ebp+sstp.y]
		movsx	eax, ax
		mov	[ebp+sstp.dy], eax
		;mov	ecx, 5
		mov	cx, 5
cDloop:
		mov	edx, [ebx+16]
		mov	[ebp+edi+sstp.edg], edx
		mov	eax, [esi+16]
		sub	eax, edx
		cdq
		cmp	word [ebp+sstp.dy], 0
		je	short cDskip
		idiv	dword [ebp+sstp.dy]
		mov	[ebp+edi+sstp.del], eax
cDskip:
		;mov	dx, 4
		;add	di, dx
		;add	si, dx
		;add	bx, dx

		mov	edx, 4
		add	edi, edx ; +4
		add	esi, edx ; +4
		add	ebx, edx ; +4

		loop	cDloop
		retn

;************************************************
;* description	: clip a poly at the viewplane, *
;*                project and draw it	        *
;* parameter	: bx:adress of the face	        *
;* sideeffect	: all		 	        *
;* back		: none			        *
;************************************************

drawclippedface:
		; 11/08/2017
		; 27/07/2017
		; 06/02/2017

		dcf.d	equ -2	  ; word
		dcf.h	equ -4	  ; word	
		dcf.j	equ -6	  ; word
		dcf.col equ -8	  ; word
		dcf.is_in equ -10 ; byte
			
		dcf.p0	equ -192  ; poly (5*36 bytes)
		dcf.p2	equ -372  ; poly (5*36 bytes)

		enter	372, 0  ; 174h
 			; push ebp ; mov ebp, esp ; sub esp, 372

		;mov	si, uvtab
		mov	esi, 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, [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, [ebx]
		; vector(4-cx).x
		mov	[ebp+edi+dcf.p0+0], eax
		; vector(4-cx).y
		mov	eax, [ebx+4]
		mov	[ebp+edi+dcf.p0+4], eax

		fld	dword [ebx+8]
		; vector(4-cx).z
		fst	dword [ebp+edi+dcf.p0+8]
		fistp	word [ebp+dcf.h]	; dcf.h = z distance
		pop	ebx

		mov	ax, [ebp+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	[ebp+edi+dcf.p0+32], edx

		xor	ah, ah
		mov	al, [esi+4]
		shl	eax, 16	; 10h
		; edges(4-cx).v
		mov	[ebp+edi+dcf.p0+24], eax

		lodsb
		shl	eax, 16	; 10h
		; edges(4-cx).u
		mov	[ebp+edi+dcf.p0+20], eax

		pop	ebx
		;inc	bx
		;inc	bx
		inc	ebx
		inc	ebx
		add	di, 36	; 24h  ; size of edge
		;loop	dCFinitloop
		;dec	cx
		dec	ecx
		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, [ebx]		; shade
		mov	[ebp+dcf.col], ax

		xor	ebx, ebx
		mov	[ebp+dcf.j], bx

		; vector(3).z
		fld	dword [ebp+dcf.p0+108+8]
		ftst
		;fstsw	ax
		fnstsw	ax
		fstp	st0
		sahf
		jae	short isFalse
		dec	bx
isFalse:
		mov	[ebp+dcf.is_in], bl
		xor	esi, esi
		xor	edi, edi 
forloop:
		; vector(0-3).z
		fld	dword [ebp+esi+dcf.p0+8]
		ftst
		;fstsw	ax
		fnstsw	ax
		fstp	st0
		sahf
		jae	short elseFall

		cmp	byte [ebp+dcf.is_in], 0FFh ; -1 ; true
		je	short inside
		call	clipsub
		; { OUT / IN }
		not	byte [ebp+dcf.is_in]
inside:
		push	edi
		push	esi
		lea	edi, [ebp+edi+dcf.p2]
		lea	esi, [ebp+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 [ebp+dcf.j]
		jmp	short dCFendif
elseFall:
		cmp	byte [ebp+dcf.is_in], 0FFh
		jne	short outside
		call	clipsub
		; { IN / OUT }
		not	byte [ebp+dcf.is_in]
outside:
dCFendif:	add	si, 36 ; 24h
		cmp	si, 4*36 ; 90h
		jne	short forloop

		mov	cx, [ebp+dcf.j]
		cmp	cx, 2
		jl	dCFnodraw
		xor	edi, edi
dCFloop:
		fild	word [CONST13]
		fsub	dword [ebp+edi+dcf.p2+8]
		fidiv	word [CONST160]
		
		fld	dword [ebp+edi+dcf.p2+4]
		fdiv	st0, st1
		fiadd	word [CONST100]
		fistp	dword [ebp+edi+dcf.p2+12]
		
		fld	dword [ebp+edi+dcf.p2]
		fmul	dword [ASPECT_PLACE]
		fdiv	st0, st1
		fiadd	word [CONST160]
		frndint
		fimul	dword [CONST65536]
		fistp	dword [ebp+edi+dcf.p2+16]

		fild	dword [ebp+edi+dcf.p2+20]
		fdiv	st0, st1
		fistp	dword [ebp+edi+dcf.p2+20]
		
		fild	dword [ebp+edi+dcf.p2+24]
		fdiv	st0, st1
		fistp	dword [ebp+edi+dcf.p2+24]
		
		fild	dword [CONST65536]
		fdiv	st0, st1
		fistp	dword [ebp+edi+dcf.p2+28]
		
		fstp	st0
		add	di, 36 ; 24h
		;loop	dCFloop
		dec	cx
		jnz	dCFloop

		lea	edi, [ebp+dcf.p2]
		; 10/08/2017
		push	edi		; 32 bits push !
		push	word [ebp+dcf.j]    ; 16 bits push !!
		push	word [ebp+dcf.col]  ; 16 bits push !!
		call	scansubtextpoly
dCFnodraw:
dCFbackclip:	leave
			; mov esp, ebp ; pop ebp
		retn

clipsub:
		; 06/04/2017
		; 05/02/2017
		push	esi
		push	edi
		;lea	ax, [esi-36]
		lea	ax, [si-36] ; 11/08/2017
		cmp	ax, 0
		jge	short cSnounder
		;mov	eax, 108 ; 6Ch
		mov	ax, 108
cSnounder:
		fld	dword [ebp+esi+dcf.p0+8]
		fld	st0
		xchg	ax, di
		fsub	dword [ebp+edi+dcf.p0+8]
		xchg	ax, di
		fdivp	st1, st0
		;fdiv

		mov	ebx, cliptab
		mov	cx, 6
		xor	edx, edx
dCFclipLoop2:
		xchg	ax, di
		fld	dword [ebp+edi+dcf.p0]
		xchg	ax, di
		fsub	dword [ebp+esi+dcf.p0]
		fmul	st0, st1
		fadd	dword [ebp+esi+dcf.p0]
		fstp	dword [ebp+edi+dcf.p2]

		mov	dl, [ebx]
		inc	ebx
		add	edi, edx
		add	esi, edx
		add	eax, edx
		loop	dCFclipLoop2
		fstp	st0
		pop	edi
		pop	esi
		inc	word [ebp+dcf.j]
		;add	edi, 36
		add	di, 36 ; 24h
		retn


;***************************************************
;* description	: 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

;***********************************************
;* description	: rotate point		       *
;* parameter	: a,b,c:angles,adr:address     *
;* sideeffect	: all		 	       *
;* back		: none			       *
;***********************************************

xyzRotate:
		; 11/08/2017
		;;push	word [ebp+xw] ; a ; 16 bits push !!
		;;push	word [ebp+yw] ; b ; 16 bits push !!
		;;push	word [ebp+zw] ; c ; 16 bits push !!
		;;add	di, nwmat
		;;push	edi	      ; adr ; 32 bits push !
		;;call	xyzRotate
		;;pop	edi

		adr	equ 8   ; arg 1, [esp+4]
		c	equ 12	; arg 2, [esp+8]	
		b	equ 14  ; arg 3, [esp+10]
		a	equ 16  ; arg 4, [esp+12]

		push	ebp
		mov	ebp, esp
	
		mov	edi, [ebp+adr] ; nwmat+

		; nwmat:	;;; edi +0 +4 +8	 	
		; loop 1 (nwmat)    : dd 1, 0, 0
		; loop 2 (nwmat+12) : dd 0, 1, 0
		; loop 3 (nwmat+24) : dd 0, 0, 1

		fild	word [ebp+a]   ; xw ; a (x angle)
		lea	ebx, [edi+8]   ; z (2. coordinate)	
		lea	esi, [edi+4]   ; y (1. coordinate)
		call	rotateAxis
		fild	word [ebp+b]   ; yw ; a (y angle)
		lea	ebx, [edi]     ; z	
		lea	esi, [edi+8]   ; y	
		call	rotateAxis
		fild	word [ebp+c]   ; zw ; a (z angle)	
		lea	ebx, [edi+4]   ; z	
		lea	esi, [edi]     ; y
		call	rotateAxis

		pop	ebp
		; 11/08/2017 
		; (pop dw, pop w, pop w, pop w)
		ret	10

;***********************************************
;* description	: calculate world matrix       *
;* parameter	: x-,y-,z-angle,neig:stack     *
;* sideeffect	: all		 	       *
;* back		: none			       *
;***********************************************

calcRotMat:
		; 11/08/2017  (16 bits pushes)

		; [esp] = [oyw]*16 ; angle or YSTEP * 16 ?		        	
		; [esp+2] = [ozw] ; ZSTEP
		; [esp+4] = [oyw] ; YSTEP
		; [esp+6] = [oxw] ; XSTEP

		neig	equ 8   ; arg 1, [esp+4]
		zw	equ 10	; arg 2, [esp+6]	
		yw	equ 12  ; arg 3, [esp+8]
		xw	equ 14  ; arg 4, [esp+10]

		push	ebp
		mov	ebp, esp

		mov	edi, nwmat
		
		identityMat
	
		; nwmat:
		; dd 1,0,0
		; dd 0,1,0
		; dd 0,0,1
		
		xor	edi, edi
cRMolp:
		push	edi
		; 11/07/2017 (16 bits pushes)
		push	word [ebp+xw] ; a (x angle)
		push	word [ebp+yw] ; b (y angle)
		push	word [ebp+zw] ; c (z angle)
		;add	edi, nwmat
		add	di, nwmat
		push	edi  ; 32 bits push  ; adr
		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
		; 11/08/2017 (16 bits pops)
		ret	8

;***********************************************
;* description	: create the world	       *
;* parameter	: none			       *
;* sideeffect	: all		               *
;* back		: none			       *
;***********************************************

createWorld:
		; 11/08/2017
		; 10/08/2017
		; 27/07/2017
		; 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	[cw.shade], bx
		and	ax, 0Fh ; 15   ; Low 4 bits for direction (29/01/2017)
		mov	[cw.direc], ax

		xor	ebx, ebx
		jmp	short cWfirstNibble ; 27/07/2017
cWsideLoop:
		test	bl, 4
		jz	short cWfirstNibble
		lodsb
		and	al, 0Fh ; 15
		jmp	short cWsecondNibble
cWfirstNibble:
		mov	al, [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	[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]
		movzx	esi, byte [ebx+cube] ; 11/02/2017
		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, [o+object.panz] ; number of points (for object.p)
		mov	cx, [object.panz] ; 10/02/2017
		;xor	ax, ax
		xor	eax, eax
		jcxz	cWfirstPoint
cWsearchPointLoop: ; check point coordinates are same or not (29/01/2017)
		mov	edx, [esi]
		cmp	edx, [edi]
		jne	short cWdifferent
		mov	dx, [esi+4]
		cmp	dx, [edi+4]
		je	short cWpointExists
cWdifferent:
		;inc	ax ; number of different points (of object)
		inc	eax
		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 number 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:
		; 27/07/2017
		;add	bx, 4
		add	bl, 4
		;cmp	bx, 24 ; 18h
		cmp	bl, 24
		;jne	cWsideLoop
		jb	cWsideLoop ; 10/08/2017

		;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, [esi]
cWpushLoop:
		xor	eax, eax
		shr	dl, 1
		jnc	short cWnoRot
		mov	ah, [esi]
		;and	ax, 0F000h
		and	ah, 0F0h
		;push	ax
		;jmp	short cWendIf
cWnoRot:
		;push	0 ; arg 2 (c), arg 3 (b), arg 4 (a)
		; 11/08/2017
		push	ax  ; 16 bits push !!
cWendIf:
		loop	cWpushLoop
		; 11/08/2017
		push	ebx ; arg 1 (addr)  ; 32 bits push !
		call	xyzRotate
		popad
		add	bx, 12 ; 0Ch
		loop	cWrotloop
		inc	esi
cWsimpleRoom:
		mov	bx, [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]
		movzx	esi, byte [ebx+cube] ; 11/02/2017
		mov	eax, esi
		add	esi, p ; + base address of 'p:'
		xor	bl, 7
		;movsx	edi, byte [ebx+cube]
		;xor	edi, edi ; 10/02/2017
		movzx	edi, byte [ebx+cube]
		add	edi, p ; + base address of 'p:'
		push	esi 
		movsd
		movsd
		pop	esi

		mov	ebx, eax
		;shr	ebx, 1
		shr	bx, 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, [cw.shade]
		mov	[esi], ax ; 4th word
		popad
		inc	ebx
		loop	cWpointCopyLoop
		jmp	cWmainLoop
cWexit:
		pop	ecx
		;dec	cx
		dec	cl ; 27/07/2017
		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	'12/08/2017'
		db	0Dh, 0Ah
		db	0 

align 4

;=============================================================================
;               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 KPPERS"
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
;=============================================================================

alignb 4	; 10/08/2017

oldstack:	resw	1
;Old08IrqPtr:
;Old08Irqofs:	resw	1
;Old08Irqseg:	resw	1
;Old09IrqPtr:
;Old09Irqofs:	resw	1
;Old09Irqseg:	resw	1
;songdata:	resb	3605
;		resb	1 
root:   	resw	1
circletab:	resw	32
stars:		resb	90
twice:		resb	1
timer_event_number:	resb 1 ; 06/02/2017
; 25/07/2017
; 11/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
; 26/07/2017
_ds:		resd	1
_es:		resd    1
_fs:		resd	1

; 11/08/2017
; 06/02/2017
cw.direc:	resw	1 ; word
cw.shade:	resw	1 ; word
;
; 12/08/2017
songdata:	resb	3605
tstatus:	resb	1  ; timer (screen update) flag

alignb 4

; 12/08/2017
shadetab:	resb	256*128

bss_end: