;ﾚﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄｿ
;ｳ  FILENAME: PPSINS.ASM  Version 1.01					     ｳ
;ｳ									     ｳ
;ｳ  DATE    : July 15, 1992						     ｳ
;ｳ                                                                           ｳ
;ｳ  Ideal Mode -- Turbo Assembler v2.01 and above			     ｳ
;ｳ                                                                           ｳ
;ｳ  DESCRIPTION: This file includes all routines for playing instruments.    ｳ
;ﾀﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾙ

	ideal				; Use TASM's Ideal mode.
	model	Small,Pascal		; Define the memory model.
	P286				; Set up for 286 instructions.
	jumps				; Have TASM automatically resolve out-
					; of-range jumps.

	include "pps.inc"

codeseg

;ﾕﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍｸ
;ｳ NAME       : sd_PlayIns                                                   ｳ
;ｳ                                                                           ｳ
;ｳ ENTRY      : AX - Period                                                  ｳ
;ｳ              BX - RepLen                                                  ｳ
;ｳ              CX - MaxRep                                                  ｳ
;ｳ              DX - Repeat                                                  ｳ
;ｳ              SI - Volume                                                  ｳ
;ｳ              ES - Sample Segment                                          ｳ
;ｳ                                                                           ｳ
;ｳ RETURN     : Carry Set - Error                                            ｳ
;ｳ              Carry Clear - Everything OK, music should be playing         ｳ
;ｳ                                                                           ｳ
;ｳ DESCRIPTION: This procedure sets up all pointers, interrupts, and the     ｳ
;ｳ              likes for the instrument specified.                          ｳ
;ｳ                                                                           ｳ
;ｳ              *** Written by Joshua C. Jensen                              ｳ
;ﾔﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍﾍｾ
proc    sd_PlayIns
        uses    ds
        push    ax
        mov     ax,@data
        mov     ds,ax
        pop     ax
        cmp     [Byte MusicPlayerInstalled],1
        jnz     @@End
        call    sd_ShutDownMusicInt
        or      si,si
        jz      @@End
        dec     si
        shl     si,2                    ; Give the effect of all four voices
                                        ; playing at once.
        shl     bx,1
        shl     cx,1
        shl     dx,1
        mov     [Channel1RepLen],bx
        mov     [Channel1MaxRep],cx
        mov     [Channel1Repeat],dx
        mov     bx,si
        mov     [Channel1Vol1],bl
        mov     [Channel1Seg],es
        mov     [Word Channel1Ofs],0
        push    ax
        call    sd_SetFreq
        pop     bx
        or      bx,bx
        jz      @@BlankPeriod
        div     bx
        mov     bx,ax
@@BlankPeriod:
        mov     [Channel1Freq],bx
        call    sd_ReturnInfo
        mov     dx,offset sd_InsInterrupt
        mov     [PlayerInterrupt],dx
        call    sd_SetMainAddr
@@SetupForIns:
        mov     [Byte TypeOfInt],2      ; Specify that the interrupt to be
                                        ; set up is the sample interrupt.
        call    sd_SetupForMusic
@@End:
        ret
endp    sd_PlayIns

;ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄｿ
;ﾚﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾙ
;ﾀﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄｿ
;ﾚﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾙ
;ﾃﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄｿ
;ｳ ******************  Instrument Playback Interrupts  **********************  ｳ
;ﾀﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄｴ
;ﾚﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾙ
;ﾀﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄｿ
;ﾚﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾙ
;ﾀﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
;ｳ The below code was written by Joshua C. Jensen.  Help was obtained from   ｳ
;ｳ several professional programmers, the most helpful being Dave Ashcroft.   ｳ
;ｳ The help was in building the initial interrupt routines around two years  ｳ
;ｳ ago.  They have since been rewritten for speed many times over by myself. ｳ
macro   sd_MonoLessIns
        xor     cx,cx
        xor     dx,dx

@@Channel1:
        cmp     [Word Channel1Seg],0    ;;<--Is the channel even on?
        jz      @@ChannelDone           ;;<--If not jump to channel 2
        mov     es,[Channel1Seg]

        mov     bx,[Channel1Ofs]
        cmp     bx,[Channel1MaxRep]
        jb      @@Channel1_1

        cmp     [Channel1RepLen],0
        jz      @@ChannelTurnInsOff

        mov     bx,[Channel1Repeat]
        mov     ax,[Channel1RepLen]
        mov     [Channel1MaxRep],ax
@@Channel1_1:
        mov     ax,[Channel1Freq]
        add     [Byte Channel1OFlow],al
        xchg    ah,cl
        adc     bx,cx
        mov     [Channel1Ofs],bx
        mov     al,[es:bx]
        xor     al,10000000b    ;<-remove the sign
	mul	[Byte Channel1Vol1]
@@ChannelDone:
        mov     al,ah
        jmp     @@DoneWithIt
@@ChannelTurnInsOff:
        mov     [Byte MStatus],1
@@DoneWithIt:
endm    sd_MonoLessIns

proc	sd_InsInterrupt near
	push	ds ax es di si bx cx dx bp
        mov     ax,@data
        mov     ds,ax
        cmp     [Byte SoundSource],1
	jnz	@@GetValueToOutput
	mov	dx,[MainAddr]
@@0:	in	al,dx
	rol	al,1
	jb	@@0
	mov	al,10h
        out     dx,al
@@GetValueToOutput:
	sd_MonoLessIns
	cmp	[Byte MStatus],1
	jz	@@FinishTheInterrupt
	mov	dx,[MainAddr]
	mov	bx,ax
	cmp	[Byte SoundSource],1
	jz	@@FinishTheSB
	cmp	[Byte SoundSource],2
	jz	@@FinishTheDAC
@@FinishTheSB:
	in	al,dx				; tell us to send.
	rol	al,1
	jb	@@FinishTheSB
	mov	ax,bx
	out	dx,al
	jmp	@@FinishTheInterrupt
@@FinishTheDAC:
	out	dx,al
	jmp	@@FinishTheInterrupt
@@FinishTheInterrupt:
@@FinishTheInterrupt2:
	pop	bp dx cx bx si di es
	pop	ax ds
	sti
	iret
endp    sd_InsInterrupt

end
