;--------------------------------------------------------------------
;                    SimplexAdlib Player
;--------------------------------------------------------------------
;              Copyright (C) 1993 Future Crew
;--------------------------------------------------------------------
;                        code: Psi
;                       music: Skaven
;--------------------------------------------------------------------;
; Modifications for PGRID Loader by Friar Tuck, outlined by comment  ;
; blocks                                                             ;
;--------------------------------------------------------------------;
;圹圹圹圹圹圹圹圹 Simplex Adlib Player 圹圹圹圹圹圹圹圹
;this doesn't just read raw data to output to adlib like the one
;used in the last starport intro. This player really does have
;note & instrument data it reads and processes!

;adlib data
a_musiccnt dw	0
a_chdelaycnt db	9 dup(0)
a_chdelay db    9 dup(0)

;adlib player data
a_inst_table LABEL BYTE
        db 20h+0,20h+1,20h+2,20h+8,20h+9,20h+10,20h+16,20h+17,20h+18
NTB equ 8192 ;+1024*1
a_note_table LABEL WORD
        dw NTB+363,NTB+385,NTB+408,NTB+432,NTB+458,NTB+485
        dw NTB+514,NTB+544,NTB+577,NTB+611,NTB+647,NTB+868
        ;note: a zero word is expected after this table (found in col0)

;北北北北北北北北 output data to adlib 北北北北北北北
a_lodsboutaw03: ;size optimization related entry (instrument loading)
	call	a_lodsboutaw
	add	ah,3
a_lodsboutaw: ;size optimization related entry (instrument loading)
	lodsb
a_outaw PROC ;ah=reg,al=data
	push	ax
	push	cx
	xchg	al,ah
	mov	dx,388h
	out	dx,al
	mov	cx,7
	call	a_wait
	mov	dx,389h
	mov	al,ah
	out	dx,al
	mov	cx,30
	call	a_wait
	pop	cx
	pop	ax
	ret
a_wait:	in	al,dx
	loop	a_wait
	ret
a_outaw	ENDP

;北北北北北北北北 load instrument to adlib 北北北北北北北
a_loadinstrument PROC
	;bx=channel, ds:si=offset to instrument data
        mov     ah,ds:a_inst_table[bx]
	mov	cx,4
@@11:   call    a_lodsboutaw03
	add	ah,20h-3
        loop    @@11
	add	ah,40h
	call	a_lodsboutaw03
	mov	ah,bl
	add	ah,0c0h
	jmp	a_lodsboutaw
a_loadinstrument ENDP

;北北北北北北北北 set note on/off 北北北北北北北
a_playnote PROC
	;bx=channel, ax=data
	push	bx
	xchg	ah,bl
	add	ah,0a0h
	call	a_outaw
	mov	al,bl
	add	ah,010h
	pop	bx
	jmp	a_outaw
a_playnote ENDP

;北北北北北北北北 initialize/clear/shutup adlib 北北北北北北北
a_init PROC
	mov	ax,00120h
	call	a_outaw
	mov	ax,00800h
	call	a_outaw
	mov	ah,0bdh
	call	a_outaw
	mov	bp,9
	xor	bx,bx
	mov	di,OFFSET music_instruments
@@12:   mov     si,ds:[di]
	add	di,2
	call	a_loadinstrument
	xor	ax,ax
	call	a_playnote
	inc	bx
	dec	bp
        jnz     @@12
	ret
a_init ENDP

;北北北北北北北北 advance music one row 北北北北北北北
a_dorow PROC
        ;-------------------------------;
        mov     cx,24                   ;
        mov     di,offset pal+222       ;
ad_01:  mov     al,byte ptr cs:[di]     ;
        sub     al,2                    ;
        js      ad_02                   ;
        mov     byte ptr cs:[di],al     ;
ad_02:  inc     di                      ;
        loop ad_01                      ;
        ;-------------------------------;
@@c:    sub     ds:a_musiccnt,1
	jnc	@@0
        mov     ds:a_musiccnt,music_speed
	mov	cx,music_channels
	mov	di,OFFSET music_patterns
	xor	bx,bx
@@13:   sub     ds:a_chdelaycnt[bx],1
	jns	@@2
        mov     si,ds:[di]
	xor	ax,ax
	call	a_playnote
        ;-------------------------------;
        push    bx                      ;
        push    ax                      ;
        mov     ax,bx                   ;
        sal     ax,1                    ;
        add     bx,ax                   ;
        add     bx,222                  ;
        mov     byte ptr cs:pal[bx],30  ;
        mov     byte ptr cs:pal[bx+1],30;
        mov     byte ptr cs:pal[bx+2],62;
        pop     ax                      ;
        pop     bx                      ;
        ;-------------------------------;
@@4:	lodsb	
	or	al,al
	jz	@@7
	jns	@@6
	sub	al,81h
        mov     ds:a_chdelay[bx],al
	lodsb
@@6:	mov	dl,al
	and	ax,15
	mov	bp,ax
	add	bp,bp
        mov     ax,ds:a_note_table[bp]
	shr	dl,2
	and	dl,not 3
	add	ah,dl
	call	a_playnote
        mov     al,ds:a_chdelay[bx]
        mov     ds:a_chdelaycnt[bx],al
        mov     ds:[di],si
@@2:	add	di,4
	inc	bx
        loop    @@13
@@0:	ret
@@7:    mov     si,ds:[di+2]
	jmp	@@4
a_dorow ENDP

