     1                                  ; ****************************************************************************
     2                                  ; omniplay.s (TRDOS 386, TRDOS v2.0 - sample binary file, 'omniplay.prg')
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; OMNIPLAY.PRG ! TEST program !
     5                                  ;
     6                                  ; 09/04/2017
     7                                  ;
     8                                  ; [ Last Modification: 09/04/2017 ]
     9                                  ;
    10                                  ; Derived from source code of 'OMNISCENT.ASM' by Dirk Kppers
    11                                  ;          SNC_OMNI.COM	 (MSDOS) intro file, 1997
    12                                  ;
    13                                  ; Assembler: NASM 2.11
    14                                  
    15                                  ; (Original TASM -msdos- code has been modifed for TRDOS 386 system calls and
    16                                  ; other protected mode (TRDOS 386) interrupts.)
    17                                  ; ****************************************************************************
    18                                  
    19                                  ;		   ----====> Omniscent <====----
    20                                  ;
    21                                  ;   Omniscent was done by Pinker of SANCTION for the Mekka '97. The song
    22                                  ;   was written by Nyphton. It place XXX out of XXX.
    23                                  ;
    24                                  ;   Special thanks in alphabetical order :
    25                                  ;
    26                                  ;       Andreas Mautsch     (beta testing)
    27                                  ;       Axel Scheel Meyer   (MACM sources, nice IRC chat's)
    28                                  ;       Christian Cohnen    (for his help on perspective texture mapping and
    29                                  ;	   		designing world and script)
    30                                  ;       Daniel Weinand	    (song)
    31                                  ;       Funk                (for give me the idea trying a 4K Descent)
    32                                  ;       Stephanie Schepers  (moral and food support ;-) )
    33                                  ;
    34                                  ;       and all other SANCTION dudes for supporting this product !
    35                                  
    36                                  ; 16/10/2016
    37                                  ; 29/04/2016
    38                                  ; TRDOS 386 system calls (temporary list!)
    39                                  _ver 	equ 0
    40                                  _exit 	equ 1
    41                                  _fork 	equ 2
    42                                  _read 	equ 3
    43                                  _write	equ 4
    44                                  _open	equ 5
    45                                  _close 	equ 6
    46                                  _wait 	equ 7
    47                                  _creat 	equ 8
    48                                  _link 	equ 9
    49                                  _unlink	equ 10
    50                                  _exec	equ 11
    51                                  _chdir	equ 12
    52                                  _time 	equ 13
    53                                  _mkdir 	equ 14
    54                                  _chmod	equ 15
    55                                  _chown	equ 16
    56                                  _break	equ 17
    57                                  _stat	equ 18
    58                                  _seek	equ 19
    59                                  _tell 	equ 20
    60                                  _mount	equ 21
    61                                  _umount	equ 22
    62                                  _setuid	equ 23
    63                                  _getuid	equ 24
    64                                  _stime	equ 25
    65                                  _quit	equ 26	
    66                                  _intr	equ 27
    67                                  _fstat	equ 28
    68                                  _emt 	equ 29
    69                                  _mdate 	equ 30
    70                                  _video 	equ 31
    71                                  _audio	equ 32
    72                                  _timer	equ 33
    73                                  _sleep	equ 34
    74                                  _msg    equ 35
    75                                  _geterr	equ 36
    76                                  _rsvd1	equ 37
    77                                  _pri	equ 38
    78                                  _rele	equ 39
    79                                  _fff	equ 40
    80                                  _fnf	equ 41
    81                                  
    82                                  [BITS 32] ; 80386 Protected Mode (32 bit) intructions
    83                                  
    84                                  %macro sys 1-4
    85                                      ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)	
    86                                      ; 03/09/2015	
    87                                      ; 13/04/2015
    88                                      ; Retro UNIX 386 v1 system call.	
    89                                      %if %0 >= 2   
    90                                          mov ebx, %2
    91                                          %if %0 >= 3    
    92                                              mov ecx, %3
    93                                              %if %0 = 4
    94                                                 mov edx, %4   
    95                                              %endif
    96                                          %endif
    97                                      %endif
    98                                      mov eax, %1
    99                                      ;int 30h
   100                                      int 40h ; TRDOS 386 (TRDOS v2.0)	   
   101                                  %endmacro
   102                                  
   103                                  ; TRDOS 386 (and Retro UNIX 386 v1) system call format:
   104                                  ; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
   105                                  
   106                                  
   107                                  ;==============================================================================
   108                                  ;		   constants
   109                                  ;==============================================================================
   110                                  
   111                                  GMPort		equ 0331h
   112                                  CMD_NOTEON      equ 090h
   113                                  CMD_NOTEOFF     equ 080h
   114                                  CMD_CHANGEPARAM equ 0B0h
   115                                  CMD_CHANGEPRG   equ 0C0h
   116                                  MOD_ALLNOTESOFF equ 07Bh
   117                                  SONGSPEED   	equ 29
   118                                  
   119                                  ;==============================================================================
   120                                  ;		   structures
   121                                  ;==============================================================================
   122                                  
   123                                  struc channel
   124 00000000 <res 00000002>           .del:	resw 1
   125 00000002 <res 00000001>           .trk:	resb 1
   126 00000003 <res 00000001>           .ln:	resb 1
   127 00000004 <res 00000002>           .adr:	resw 1
   128                                  endstruc
   129                                  
   130                                  ;==============================================================================
   131                                  ;		      %macros
   132                                  ;==============================================================================
   133                                  ;***********************************************
   134                                  ;* descript. : start timer interrupt 70/s      *
   135                                  ;* parameter : none			       *
   136                                  ;* sideeffect: all		 	       *
   137                                  ;* back      : none			       *
   138                                  ;***********************************************
   139                                  %macro		startTimer 0
   140                                                  ;mov     ax,03508h
   141                                                  ;int     21h
   142                                                  ;mov     [word ptr Old08Irqseg],es
   143                                                  ;mov     [word ptr Old08Irqofs],bx
   144                                                  ;mov     ax,02508h
   145                                                  ;mov     dx,offset irqHandler08
   146                                                  ;int     21h
   147                                  		
   148                                  		mov	bx, 3409 ; 1193180/3409 = 350 ticks per second (*!)
   149                                  		call	setTimer
   150                                  
   151                                  		; start timer event
   152                                  		mov	ebx, 8400h ; Current Timer setup, Callback method 	
   153                                  		mov	ecx, 1	 ; 1 tick 
   154                                  		mov	edx, timer_callback ; timer callback service addr
   155                                  		mov	eax, 33	; 'systimer'
   156                                  		int	40h	; TRDOS 386 system call
   157                                  		jc	short _err_exit
   158                                  
   159                                  		mov	[timer_event_number], al 
   160                                  
   161                                  %endmacro
   162                                  
   163                                  ;***********************************************
   164                                  ;* descript. : stop timer interrupt            *
   165                                  ;* parameter : none			       *
   166                                  ;* sideeffect: all		 	       *
   167                                  ;* back      : none			       *
   168                                  ;***********************************************
   169                                  %macro		stopTimer 0
   170                                                  ;push    ds
   171                                                  ;xor     bx,bx                  ; set timer to default
   172                                                  ;call    setTimer		; 18.2 ticks per second
   173                                                  ;mov     ax,02508h              ; restore old IRQ-vector
   174                                                  ;lds     dx,[Old08Irqptr]
   175                                                  ;int     21h
   176                                                  ;pop     ds
   177                                  
   178                                  		xor	bx, bx	; set timer to default (18.2 Hz) value
   179                                  		call	setTimer
   180                                  
   181                                  		; Stop timer event
   182                                  		movzx	ebx, byte [timer_event_number]
   183                                  		;and	bl, bl
   184                                  		;jz	short r_t_m ; 0 = error (no timer event)
   185                                   		; bh = 0 -> stop timer event
   186                                  		mov	eax, 33	; 'systimer'
   187                                  		int	40h	; TRDOS 386 system call
   188                                  ;r_t_m:
   189                                  %endmacro
   190                                  
   191                                  ;***********************************************
   192                                  ;* descript. : start keyboard handler          *
   193                                  ;* parameter : none			       *
   194                                  ;* sideeffect: all		 	       *
   195                                  ;* back      : none			       *
   196                                  ;***********************************************
   197                                  %macro		startKBDHandler 0
   198                                                  ;mov     ax,03509h
   199                                                  ;int     21h
   200                                                  ;mov     [word ptr Old09Irqseg],es
   201                                                  ;mov     [word ptr Old09Irqofs],bx
   202                                                  ;mov     ax,02509h
   203                                                  ;mov     dx,offset irqHandler09
   204                                                  ;int     21h
   205                                  
   206                                  		; TRDOS 386 already have a CRTL+BRK
   207                                  		; preview feature to call 'sysexit'
   208                                  		; /// nothing to do here ! ///
   209                                  		; 10/12/2016 - Erdogan Tan
   210                                  		nop
   211                                  %endmacro
   212                                  
   213                                  ;***********************************************
   214                                  ;* descript. : stop keyboard handler           *
   215                                  ;* parameter : none			       *
   216                                  ;* sideeffect: all		               *
   217                                  ;* back      : none		               *
   218                                  ;***********************************************
   219                                  %macro		stopKBDHandler 0
   220                                                  ;push    ds
   221                                                  ;mov     ax,02509h             ; restore old IRQ-vector
   222                                                  ;lds     dx,[Old09Irqptr]      ;
   223                                                  ;int     21h
   224                                                  ;pop     ds
   225                                  
   226                                  		; TRDOS 386 already have a CRTL+BRK
   227                                  		; preview feature to call 'sysexit'
   228                                  		; /// nothing to do here ! ///
   229                                  		; 10/12/2016 - Erdogan Tan
   230                                  		nop
   231                                  %endmacro
   232                                  
   233                                  ;***********************************************
   234                                  ;* descript. : zero null-initialized data      *
   235                                  ;* parameter : none			       *
   236                                  ;* sideeffect: all		               *
   237                                  ;* back      : none		               *
   238                                  ;***********************************************
   239                                  %macro		nullData 0
   240                                  		;mov	di, nullstart
   241                                                  mov	edi, nullstart
   242                                  		;mov	cx, nullend-nullstart
   243                                                  ;mov	ecx, nullend-nullstart ; ??
   244                                  		xor	eax, eax
   245                                                  ;rep	stosb
   246                                  		mov	ecx, (bss_end-nullstart)+3 ; 06/02/2017
   247                                  		shr	cx, 2
   248                                  		rep	stosd
   249                                  %endmacro
   250                                  
   251                                  ;***********************************************
   252                                  ;* descript. : reset the GM-Port and switch to *
   253                                  ;*             UART mode.		       *
   254                                  ;* parameter : none			       *
   255                                  ;* sideeffect: dx,al		               *
   256                                  ;* back      : none		               *
   257                                  ;***********************************************
   258                                  %macro		resetGM 0
   259                                  		mov	dx, GMPort
   260                                  		mov	al, 0FFh
   261                                  		;out	dx, al
   262                                  	
   263                                  		mov	ah, 1 ; out (byte)
   264                                  		int	34h ; TRDOS 386 - IOCTL interrupt
   265                                  		; cl = 0
   266                                  		dec	ah ; 0
   267                                  		;sub	cl, cl
   268                                  resGMbusy1:
   269                                  		dec	cl
   270                                  		jz	short rGMerror	;{ timeout }
   271                                  		;in	al, dx		;{ read acknowledge }
   272                                  		
   273                                  		;mov	ah, 0 ; in (byte)
   274                                  		int	34h ; TRDOS 386 - IOCTL interrupt
   275                                  		
   276                                  		test	al, 80h
   277                                  		jnz	short resGMbusy1
   278                                  		dec	dx
   279                                  		;in	al, dx
   280                                  
   281                                  		;mov	ah, 0 ; in (byte)
   282                                  		int	34h ; TRDOS 386 - IOCTL interrupt
   283                                  
   284                                  		cmp	al, 0FEh
   285                                  		jne	short rGMerror
   286                                  		inc	dx		;{ switch into UART mode }
   287                                  resGMbusy2:
   288                                  		;in	al, dx
   289                                  
   290                                  		;mov	ah, 0 ; in (byte)
   291                                  		int	34h ; TRDOS 386 - IOCTL interrupt
   292                                  		
   293                                  		test	al, 40h
   294                                  		jnz	short resGMbusy2
   295                                  		mov	al, 3Fh
   296                                  		;out	dx, al
   297                                  
   298                                  		;mov	ah, 1 ; out (byte)
   299                                  		inc	ah ; 1
   300                                  		int	34h ; TRDOS 386 - IOCTL interrupt
   301                                  rGMerror:
   302                                  %endmacro
   303                                  
   304                                  ;***********************************************
   305                                  ;* descript. : mute midi channels 0..15        *
   306                                  ;* parameter : none                	       *
   307                                  ;* sideeffect: ax,cx		               *
   308                                  ;* back		 : none                	       *
   309                                  ;***********************************************
   310                                  %macro		silence 0
   311                                  		mov	cx, 15 ; 0Fh
   312                                  Siloop:	
   313                                  		mov	ax, cx
   314                                  		add	al, CMD_CHANGEPARAM ; 0B0h
   315                                  		call	writeGM
   316                                  		mov	al, MOD_ALLNOTESOFF ; 7Bh
   317                                  		call	writeGM
   318                                  		xor	al, al
   319                                  		call	writeGM
   320                                  		loop	Siloop
   321                                  Sinosound:
   322                                  %endmacro
   323                                  
   324                                  ;***********************************************
   325                                  ;* descript. : expand a song       	       *
   326                                  ;* parameter : si:song base adress	       *
   327                                  ;* sideeffect: ax,bx,cx,dx,si,di               *
   328                                  ;* back      : none                	       *
   329                                  ;***********************************************
   330                                  %macro		expandSong 0
   331                                                  mov	esi, credits
   332                                                  mov	ebx, channels
   333                                                  mov	edi, songdata
   334                                  EPSwhile:	lodsw
   335                                                  dec	al
   336                                                  js      short EPSendwhile
   337                                                  mov	[ebx+channel.trk], al ; [ebx+2]
   338                                                  add	al, CMD_CHANGEPRG ; 0C0h
   339                                                  call	setinstr
   340                                                  mov	[ebx+channel.adr], di ; [ebx+4]	
   341                                                 	call	expand
   342                                                  xor	al, al
   343                                                  stosb
   344                                                  add	bx, 6
   345                                                  inc	word [tracks]
   346                                                  jmp	short EPSwhile
   347                                  EPSendwhile:
   348                                  %endmacro
   349                                  
   350                                  ;***********************************************
   351                                  ;* descript. : play a tick of the song	       *
   352                                  ;* parameter : none                	       *
   353                                  ;* sideeffect: ax,bx,cx,dx,si		       *
   354                                  ;* back      : none                	       *
   355                                  ;***********************************************
   356                                  %macro		playsong 0
   357                                  		;mov	cx, [tracks]
   358                                  		movzx	ecx, word [tracks] ; ??
   359                                  		;mov	si, channels
   360                                  		mov	esi, channels
   361                                  PSmloop:
   362                                  		dec	word [esi+channel.del]
   363                                  		jg	short PSdelayed
   364                                  		mov	ax, [esi+channel.trk]
   365                                  		add	al, CMD_NOTEOFF	; 80h
   366                                  		call	setnote
   367                                  		;mov	bx, [esi+channel.adr]
   368                                  		movzx	ebx, word [esi+channel.adr] ; ??
   369                                  		mov	ah, 127 	; 7Fh
   370                                  		cmp	byte [ebx], 0
   371                                  		jz	short PStrackend
   372                                  		mov	ah, [ebx]
   373                                  		mov	[esi+channel.ln], ah
   374                                  		mov	al, [esi+channel.trk]
   375                                  		add	al, CMD_NOTEON	; 90h
   376                                  		call	setnote
   377                                  		mov	al, [ebx+1]
   378                                  		mov	bl, SONGSPEED	; 1Dh
   379                                  		mul	bl
   380                                  PStrackend:
   381                                  		mov	[esi+channel.del], ax
   382                                  		add	word [esi+channel.adr], 2
   383                                  PSdelayed:
   384                                  		add	si, 6
   385                                  		loop	PSmloop
   386                                  PSnosound:
   387                                  %endmacro
   388                                  
   389                                  ;=============================================================================
   390                                  ;               entry point
   391                                  ;=============================================================================
   392                                  ;***********************************************
   393                                  ;* descript. : entry point		       *
   394                                  ;* parameter : none		               *
   395                                  ;* sideeffect: all		               *
   396                                  ;* back      : none		               *
   397                                  ;***********************************************
   398                                  
   399                                  [ORG 0] 
   400                                  
   401                                  start:
   402                                  		; clear bss (18/12/2016)
   403                                  		;mov	edi, bss_start ; ??		
   404 00000000 66BF[3903]              		mov	di, bss_start
   405 00000004 66B99E03                		mov	cx, (bss_end - bss_start)/4
   406                                  		;mov	ecx, (bss_end - bss_start)/4
   407 00000008 31C0                    		xor	eax, eax
   408 0000000A F3AB                    		rep	stosd
   409                                  
   410                                  		sys	_msg, prg_msg, 255, 0Fh
   410                              <1> 
   410                              <1> 
   410                              <1> 
   410                              <1> 
   410                              <1>  %if %0 >= 2
   410 0000000C BB[BA010000]        <1>  mov ebx, %2
   410                              <1>  %if %0 >= 3
   410 00000011 B9FF000000          <1>  mov ecx, %3
   410                              <1>  %if %0 = 4
   410 00000016 BA0F000000          <1>  mov edx, %4
   410                              <1>  %endif
   410                              <1>  %endif
   410                              <1>  %endif
   410 0000001B B823000000          <1>  mov eax, %1
   410                              <1> 
   410 00000020 CD40                <1>  int 40h
   411                                  
   412                                  		resetGM
   412 00000022 66BA3103            <1>  mov dx, GMPort
   412 00000026 B0FF                <1>  mov al, 0FFh
   412                              <1> 
   412                              <1> 
   412 00000028 B401                <1>  mov ah, 1
   412 0000002A CD34                <1>  int 34h
   412                              <1> 
   412 0000002C FECC                <1>  dec ah
   412                              <1> 
   412                              <1> resGMbusy1:
   412 0000002E FEC9                <1>  dec cl
   412 00000030 741C                <1>  jz short rGMerror
   412                              <1> 
   412                              <1> 
   412                              <1> 
   412 00000032 CD34                <1>  int 34h
   412                              <1> 
   412 00000034 A880                <1>  test al, 80h
   412 00000036 75F6                <1>  jnz short resGMbusy1
   412 00000038 664A                <1>  dec dx
   412                              <1> 
   412                              <1> 
   412                              <1> 
   412 0000003A CD34                <1>  int 34h
   412                              <1> 
   412 0000003C 3CFE                <1>  cmp al, 0FEh
   412 0000003E 750E                <1>  jne short rGMerror
   412 00000040 6642                <1>  inc dx
   412                              <1> resGMbusy2:
   412                              <1> 
   412                              <1> 
   412                              <1> 
   412 00000042 CD34                <1>  int 34h
   412                              <1> 
   412 00000044 A840                <1>  test al, 40h
   412 00000046 75FA                <1>  jnz short resGMbusy2
   412 00000048 B03F                <1>  mov al, 3Fh
   412                              <1> 
   412                              <1> 
   412                              <1> 
   412 0000004A FEC4                <1>  inc ah
   412 0000004C CD34                <1>  int 34h
   412                              <1> rGMerror:
   413                                  		expandSong
   413 0000004E BE[F4010000]        <1>  mov esi, credits
   413 00000053 BB[3E030000]        <1>  mov ebx, channels
   413 00000058 BF[9F030000]        <1>  mov edi, songdata
   413 0000005D 66AD                <1> EPSwhile: lodsw
   413 0000005F FEC8                <1>  dec al
   413 00000061 7823                <1>  js short EPSendwhile
   413 00000063 884302              <1>  mov [ebx+channel.trk], al
   413 00000066 04C0                <1>  add al, CMD_CHANGEPRG
   413 00000068 E840010000          <1>  call setinstr
   413 0000006D 66897B04            <1>  mov [ebx+channel.adr], di
   413 00000071 E8D0000000          <1>  call expand
   413 00000076 30C0                <1>  xor al, al
   413 00000078 AA                  <1>  stosb
   413 00000079 6683C306            <1>  add bx, 6
   413 0000007D 66FF05[3C030000]    <1>  inc word [tracks]
   413 00000084 EBD7                <1>  jmp short EPSwhile
   413                              <1> EPSendwhile:
   414                                  
   415                                  		startTimer
   415                              <1> 
   415                              <1> 
   415                              <1> 
   415                              <1> 
   415                              <1> 
   415                              <1> 
   415                              <1> 
   415                              <1> 
   415 00000086 66BB510D            <1>  mov bx, 3409
   415 0000008A E8D9000000          <1>  call setTimer
   415                              <1> 
   415                              <1> 
   415 0000008F BB00840000          <1>  mov ebx, 8400h
   415 00000094 B901000000          <1>  mov ecx, 1
   415 00000099 BA[F4000000]        <1>  mov edx, timer_callback
   415 0000009E B821000000          <1>  mov eax, 33
   415 000000A3 CD40                <1>  int 40h
   415 000000A5 720F                <1>  jc short _err_exit
   415                              <1> 
   415 000000A7 A2[9E030000]        <1>  mov [timer_event_number], al
   415                              <1> 
   416                                  		startKBDHandler
   416                              <1> 
   416                              <1> 
   416                              <1> 
   416                              <1> 
   416                              <1> 
   416                              <1> 
   416                              <1> 
   416                              <1> 
   416                              <1> 
   416                              <1> 
   416                              <1> 
   416                              <1> 
   416 000000AC 90                  <1>  nop
   417                                  mainloop:
   418 000000AD 90                      		nop
   419 000000AE 90                      		nop
   420 000000AF 90                      		nop
   421 000000B0 B401                    		mov	ah, 1	; Check keyboard buffer
   422 000000B2 CD32                    		int	32h	; TRDOS 386 Keyboard interrupt
   423                                  		;jnz	_exit_  ; exit
   424                                  		;jmp	mainloop
   425 000000B4 74F7                    		jz	mainloop ; 11/02/2017
   426                                  _err_exit:
   427                                  _exit_:
   428                                  		silence
   428 000000B6 66B90F00            <1>  mov cx, 15
   428                              <1> Siloop:
   428 000000BA 6689C8              <1>  mov ax, cx
   428 000000BD 04B0                <1>  add al, CMD_CHANGEPARAM
   428 000000BF E8BB000000          <1>  call writeGM
   428 000000C4 B07B                <1>  mov al, MOD_ALLNOTESOFF
   428 000000C6 E8B4000000          <1>  call writeGM
   428 000000CB 30C0                <1>  xor al, al
   428 000000CD E8AD000000          <1>  call writeGM
   428 000000D2 E2E6                <1>  loop Siloop
   428                              <1> Sinosound:
   429                                  		stopKBDHandler
   429                              <1> 
   429                              <1> 
   429                              <1> 
   429                              <1> 
   429                              <1> 
   429                              <1> 
   429                              <1> 
   429                              <1> 
   429                              <1> 
   429                              <1> 
   429 000000D4 90                  <1>  nop
   430                                  		stopTimer
   430                              <1> 
   430                              <1> 
   430                              <1> 
   430                              <1> 
   430                              <1> 
   430                              <1> 
   430                              <1> 
   430                              <1> 
   430 000000D5 6631DB              <1>  xor bx, bx
   430 000000D8 E88B000000          <1>  call setTimer
   430                              <1> 
   430                              <1> 
   430 000000DD 0FB61D[9E030000]    <1>  movzx ebx, byte [timer_event_number]
   430                              <1> 
   430                              <1> 
   430                              <1> 
   430 000000E4 B821000000          <1>  mov eax, 33
   430 000000E9 CD40                <1>  int 40h
   430                              <1> 
   431                                  terminate:
   432                                  		sys 	_exit   ; INT 40h
   432                              <1> 
   432                              <1> 
   432                              <1> 
   432                              <1> 
   432                              <1>  %if %0 >= 2
   432                              <1>  mov ebx, %2
   432                              <1>  %if %0 >= 3
   432                              <1>  mov ecx, %3
   432                              <1>  %if %0 = 4
   432                              <1>  mov edx, %4
   432                              <1>  %endif
   432                              <1>  %endif
   432                              <1>  %endif
   432 000000EB B801000000          <1>  mov eax, %1
   432                              <1> 
   432 000000F0 CD40                <1>  int 40h
   433                                  here:
   434 000000F2 EBFE                    		jmp	short here
   435                                  
   436                                  ;==============================================================================
   437                                  ;		interrupt handler
   438                                  ;==============================================================================
   439                                  ;***********************************************
   440                                  ;* descript. : timer routine                   *
   441                                  ;* parameter : none		               *
   442                                  ;* sideeffect: none		               *
   443                                  ;* back      : none		               *
   444                                  ;***********************************************
   445                                  
   446                                  timer_callback:
   447                                  		playsong
   447                              <1> 
   447 000000F4 0FB70D[3C030000]    <1>  movzx ecx, word [tracks]
   447                              <1> 
   447 000000FB BE[3E030000]        <1>  mov esi, channels
   447                              <1> PSmloop:
   447 00000100 66FF0E              <1>  dec word [esi+channel.del]
   447 00000103 7F34                <1>  jg short PSdelayed
   447 00000105 668B4602            <1>  mov ax, [esi+channel.trk]
   447 00000109 0480                <1>  add al, CMD_NOTEOFF
   447 0000010B E890000000          <1>  call setnote
   447                              <1> 
   447 00000110 0FB75E04            <1>  movzx ebx, word [esi+channel.adr]
   447 00000114 B47F                <1>  mov ah, 127
   447 00000116 803B00              <1>  cmp byte [ebx], 0
   447 00000119 7416                <1>  jz short PStrackend
   447 0000011B 8A23                <1>  mov ah, [ebx]
   447 0000011D 886603              <1>  mov [esi+channel.ln], ah
   447 00000120 8A4602              <1>  mov al, [esi+channel.trk]
   447 00000123 0490                <1>  add al, CMD_NOTEON
   447 00000125 E876000000          <1>  call setnote
   447 0000012A 8A4301              <1>  mov al, [ebx+1]
   447 0000012D B31D                <1>  mov bl, SONGSPEED
   447 0000012F F6E3                <1>  mul bl
   447                              <1> PStrackend:
   447 00000131 668906              <1>  mov [esi+channel.del], ax
   447 00000134 6683460402          <1>  add word [esi+channel.adr], 2
   447                              <1> PSdelayed:
   447 00000139 6683C606            <1>  add si, 6
   447 0000013D E2C1                <1>  loop PSmloop
   447                              <1> PSnosound:
   448                                  
   449 0000013F B827000000              		mov	eax, 39	; 'sysrele'
   450 00000144 CD40                    		int	40h	; TRDOS 386 system call
   451                                  	
   452                                  ;==============================================================================
   453                                  ;		sub routines
   454                                  ;==============================================================================
   455                                  
   456                                  expand:
   457 00000146 8A0E                    EPwhile: 	mov	cl, byte [esi]
   458 00000148 08C9                    		or	cl, cl
   459 0000014A 7418                    		jz	short EPendwhile
   460 0000014C 7912                    		jns	short EPnote
   461                                  EPcall:
   462 0000014E 51                      		push	ecx
   463 0000014F 56                      		push	esi
   464 00000150 46                      		inc	esi
   465 00000151 E8F0FFFFFF              		call	expand
   466 00000156 5E                      		pop	esi
   467 00000157 59                      		pop	ecx
   468 00000158 FEC1                    		inc	cl
   469 0000015A 75F2                    		jnz	short EPcall
   470 0000015C 89C6                    		mov	esi, eax
   471 0000015E EBE6                    		jmp	short EPwhile 
   472                                  EPnote:
   473 00000160 66A5                    		movsw
   474 00000162 EBE2                    		jmp	short EPwhile
   475                                  EPendwhile:
   476 00000164 46                      		inc	esi
   477 00000165 89F0                    		mov	eax, esi
   478 00000167 C3                      		retn
   479                                  
   480                                  ;***********************************************
   481                                  ;* descript. : set timer speed to 1193180/AX   *
   482                                  ;*             interrupts per second           *
   483                                  ;* parameter : bx		               *
   484                                  ;* sideeffect: ax		               *
   485                                  ;* back      : none		               *
   486                                  ;***********************************************
   487                                  
   488                                  setTimer:	; set timer speed to 1193180/BX (TRDOS 386)
   489 00000168 B036                    		mov	al, 36h
   490                                  		;out	43h, al		; Timer	8253-5 (AT: 8254.2).
   491                                  
   492 0000016A B401                    		mov	ah, 1 ; out (byte)
   493 0000016C 66BA4300                		mov	dx, 43h
   494 00000170 CD34                    		int	34h ; TRDOS 386 - IOCTL interrupt
   495                                  
   496 00000172 88D8                    		mov	al, bl
   497                                  		;out	40h, al		; Timer	8253-5 (AT: 8254.2).
   498                                  		
   499 00000174 66BA4000                		mov	dx, 40h
   500                                  		;mov	ah, 1 ; out (byte)
   501 00000178 CD34                    		int	34h ; TRDOS 386 - IOCTL interrupt
   502                                  
   503 0000017A 88F8                    		mov	al, bh
   504                                  		;out	40h, al		; Timer	8253-5 (AT: 8254.2).
   505                                  		
   506                                  		;mov	ah, 1 ; out (byte)
   507                                  		;mov	dx, 40h
   508 0000017C CD34                    		int	34h ; TRDOS 386 - IOCTL interrupt
   509                                  
   510 0000017E C3                      		retn
   511                                  
   512                                  ;***********************************************
   513                                  ;* descript. : send a byte to the GM-Port      *
   514                                  ;* parameter : al:midi command                 *
   515                                  ;* sideeffect: dx		               *
   516                                  ;* back      : none		               *
   517                                  ;***********************************************
   518                                  
   519                                  writeGM:
   520 0000017F 66BA3103                		mov	dx, GMPort  ; 331h
   521 00000183 6651                    		push	cx
   522 00000185 6650                    		push	ax
   523 00000187 30C9                    		xor	cl, cl
   524                                  busy:
   525 00000189 FEC9                    		dec	cl
   526 0000018B 7408                    		jz	short timeOut
   527                                  		;in	al, dx
   528                                  
   529 0000018D B400                    		mov	ah, 0	; in (byte)
   530 0000018F CD34                      		int	34h	; TRDOS 386 - IOCTL interrupt
   531                                  		
   532 00000191 A840                    		test	al, 40h
   533 00000193 75F4                    		jnz	short busy
   534                                  
   535                                  timeOut:				; CODE XREF: writeGM+8j
   536 00000195 6658                    		pop	ax
   537 00000197 6659                    		pop	cx
   538 00000199 664A                    		dec	dx
   539                                  		;out	dx, al
   540                                  		
   541 0000019B B401                    		mov	ah, 1	; out (byte)
   542 0000019D CD34                      		int	34h	; TRDOS 386 - IOCTL interrupt
   543                                  
   544 0000019F C3                      		retn
   545                                  
   546                                  ;***********************************************
   547                                  ;* descript. : send NOTEON command, volume 127 *
   548                                  ;* parameter : al:channel;ah:note              *
   549                                  ;* sideeffect: dx,al		               *
   550                                  ;* back      : none		               *
   551                                  ;***********************************************
   552                                  
   553                                  setnote:
   554 000001A0 E808000000              		call	setinstr
   555 000001A5 B07F                    		mov	al, 127	; 7Fh
   556 000001A7 E8D3FFFFFF              		call	writeGM
   557 000001AC C3                      		retn
   558                                  
   559                                  ;***********************************************
   560                                  ;* descript. : send CHANGEPRG command	       *
   561                                  ;* parameter : al:channel;ah:instrument        *
   562                                  ;* sideeffect: dx,al		               *
   563                                  ;* back      : none		               *
   564                                  ;***********************************************
   565                                  
   566                                  setinstr:
   567 000001AD E8CDFFFFFF              		call	writeGM
   568 000001B2 88E0                    		mov	al, ah
   569 000001B4 E8C6FFFFFF              		call	writeGM
   570 000001B9 C3                      		retn
   571                                  
   572                                  prg_msg:
   573 000001BA 4552444F47414E2054-     		db	'ERDOGAN TAN - TRDOS 386 Test - OMNIPLAY.PRG'
   573 000001C3 414E202D205452444F-
   573 000001CC 532033383620546573-
   573 000001D5 74202D204F4D4E4950-
   573 000001DE 4C41592E505247     
   574 000001E5 0D0A                    		db	0Dh, 0Ah
   575 000001E7 30392F30342F323031-     		db	'09/04/2017'
   575 000001F0 37                 
   576 000001F1 0D0A                    		db	0Dh, 0Ah
   577 000001F3 00                      		db	0 
   578                                  
   579                                  align 4
   580                                  
   581                                  ;=============================================================================
   582                                  ;               preinitialized data
   583                                  ;=============================================================================
   584                                  
   585                                  credits:
   586 000001F4 0250FB                  		db	 2, 80,-5
   587 000001F7 FE320445023E024502-     		db      -2,50,4,69,2,62,2,69,2,81,2,62,2,69,2,79,2,62,2,69,2
   587 00000200 51023E0245024F023E-
   587 00000209 024502             
   588 0000020C 51023E0245024F0251-     		db	81,2,62,2,69,2,79,2,81,2,0	; { pat 0,2,4,6,8 }
   588 00000215 0200               
   589 00000217 FE320446023E024602-     		db      -2,50,4,70,2,62,2,70,2,81,2,62,2,70,2,79,2,62,2,70,2
   589 00000220 51023E0246024F023E-
   589 00000229 024602             
   590 0000022C 52023E0246024F0252-     		db	82,2,62,2,70,2,79,2,82,2,0	; { pat 1,3,5,7,9 }
   590 00000235 0200               
   591 00000237 00                      		db       0
   592 00000238 37203820                		db      55,32,56,32			; { pat 10 }
   593 0000023C 332035183708            		db      51,32,53,24,55,8                ; { pat 11 }
   594 00000242 39203220                		db      57,32,50,32		 	; { pat 12 }
   595 00000246 3C303A083908            		db      60,48,58,8,57,8                 ; { pat 13 }
   596 0000024C 3740                    		db      55,64		   		; { pat 14 }
   597 0000024E FE43103E1045104610-     		db      -2,67,16,62,16,69,16,70,16,0	; { pat 15 }
   597 00000257 00                 
   598 00000258 FE461045103E104110-     		db      -2,70,16,69,16,62,16,65,16,0    ; { pat 16 }
   598 00000261 00                 
   599 00000262 00                      		db       0
   600 00000263 043201800180            		db       4, 50,1,128,1,128              ;{ pat 0-3 }
   601 00000269 411C4002410240103E-     		db      65,28,64,2,65,2,64,16,62,8,60,8 ;{ pat 4 }
   601 00000272 083C08             
   602 00000275 431C41043C10410840-     		db      67,28,65,4,60,16,65,8,64,8      ;{ pat 5 }
   602 0000027E 08                 
   603 0000027F 3E20321040084108        		db      62,32,50,16,64,8,65,8           ;{ pat 6 }
   604 00000287 43203C103E084008        		db      67,32,60,16,62,8,64,8           ;{ pat 7 }
   605 0000028F 3E80                    		db      62,128		  		;{ pat 8,9 }
   606 00000291 4380                    		db      67,128		  		;{ pat 10,11 }
   607 00000293 431040104210400842-     		db     	67,16,64,16,66,16,64,8,66,8	;{ pat 12 }
   607 0000029C 08                 
   608 0000029D 48304610                		db     	72,48,70,16                 	;{ pat 13 }
   609 000002A1 43203720                		db     	67,32,55,32                 	;{ pat 14 }
   610 000002A5 FE1F20372000            		db     	-2,31,32,55,32,0                ;{ pat 15 }
   611 000002AB FE1A20322000            		db      -2,26,32,50,32,0                ;{ pat 16 }
   612 000002B1 00                      		db       0
   613 000002B2 0559FB018000            		db       5, 89,-5,1,128,0		;{ pat 0-9 }
   614 000002B8 43084A1844084B18        		db      67,8,74,24,68,8,75,24           ;{ pat 10 }
   615 000002C0 3F0846183C08451043-     		db      63,8,70,24,60,8,69,16,67,8      ;{ pat 11 }
   615 000002C9 08                 
   616 000002CA 3E08451043083E0842-     		db      62,8,69,16,67,8,62,8,66,24	;{ pat 12 }
   616 000002D3 18                 
   617 000002D4 3F0843183C08431045-     		db      63,8,67,24,60,8,67,16,69,8	;{ pat 13 }
   617 000002DD 08                 
   618 000002DE 370843182B083218        		db      55,8,67,24,43,8,50,24           ;{ pat 14 }
   619 000002E6 FE1F01263F00            		db      -2,31,1,38,63,0                	;{ pat 15 }
   620 000002EC FE1A01213F00            		db      -2,26,1,33,63,0                	;{ pat 16 }
   621 000002F2 00                      		db       0
   622 000002F3 0A00F02A022A022A02-     		db	10,  0,-16,42,2,42,2,42,2,42,1,42,1,0 ;{ pat 0,1 }
   622 000002FC 2A012A0100         
   623 00000301 F024022A022A022A01-     		db     -16,36,2,42,2,42,2,42,1,42,1,0   ;{ pat 2,3 }
   623 0000030A 2A0100             
   624 0000030D E224022A022E022401-     		db     -30,36,2,42,2,46,2,36,1,42,1,38,2
   624 00000316 2A012602           
   625 0000031A 2A022E0226012A01        		db	42,2,46,2,38,1,42,1     	;{ pat 4-16 }
   626 00000322 2402260224022A012A-     		db      36,2,38,2,36,2,42,1,42,1,38,2,42,2,46,2,38,1,42,1,0
   626 0000032B 0126022A022E022601-
   626 00000334 2A0100             
   627 00000337 00                      		db     	 0
   628 00000338 00                      		db	 0
   629                                  
   630                                  bss_start:
   631                                  
   632                                  ABSOLUTE bss_start
   633                                  
   634 00000339 <res 00000003>          alignb 4
   635                                  
   636                                  ;=============================================================================
   637                                  ;        	null-initialized data
   638                                  ;=============================================================================
   639                                  
   640                                  nullstart:
   641 0000033C <res 00000002>          tracks:		resw	1
   642 0000033E <res 00000060>          channels:       resb	16*6
   643                                  nullend:
   644                                  
   645                                  ;=============================================================================
   646                                  ;       	uninitialized data
   647                                  ;=============================================================================
   648                                  
   649 0000039E <res 00000001>          timer_event_number: resb 1
   650 0000039F <res 00000E15>          songdata:	resb	3605
   651                                  
   652                                  bss_end:
