;	
;	clipuvia.s
;
;	P/ECE Signetics 2637 UVI(Universal Video Interface) Emulator
;
;	CLiP - Common Library for P/ECE
;	Copyright (C) 2001-2005 Naoyuki Sawa
;
;	* Sat Apr 30 13:14:00 JST 2005 Naoyuki Sawa
;	- 作成開始。
;
#define UVI_DEFINE_OFFSET
#include "clipuvia.h"
#ifdef UVI_ASM

	.code
	.align	1

;****************************************************************************
;	内部関数 (Video)
;****************************************************************************


;****************************************************************************
;	内部関数 (Sound)
;****************************************************************************

#define	NTSC_COLOR_SUBCARRIER 3579545	; -> clipemu.h
#define UVIBUFLEN 320			; -> clipuvi.h
#define UVI_VOLUME_SHIFT ((16-5)+1)	; -> clipuvi.c

;----------------------------------------------------------------------------

;
;	void uvi_tone_mix(short wbuff[/*UVIBUFLEN*/], int volume, int period)
;
	.global	uvi_tone_mix
uvi_tone_mix:
	xld.uh	%r4, [uvi+TONE_POLAR]		; %r4 = polar = uvi.tone_polar /* 取り出し */
	xld.w	%r5, [uvi+TONE_COUNT]		; %r5 = count = uvi.tone_count /* 取り出し */
	;
	not	%r10, %r13			; %r10 = -volume
	xadd	%r10, %r10, 1
	;
	xcmp	%r4, 0				; %r11 = output = polar ? volume : -volume
	jrne.d	3
	ld.w	%r11, %r13			; *delay*
	ld.w	%r11, %r10			; (skip?)
	;
	xld.w	%r6, NTSC_COLOR_SUBCARRIER	; %r6 = NTSC_COLOR_SUBCARRIER
	xld.w	%r7, UVIBUFLEN			; %r7 = i = UVIBUFLEN
uvi_tone_mix_DO:
	sub	%r5, %r6			; count -= NTSC_COLOR_SUBCARRIER
	xjruge	uvi_tone_mix_NO_ADVANCE		; if(NonCarry) goto NO_ADVANCE
	;
uvi_tone_mix_ADVANCE:
	add	%r5, %r14			; count += period
	xjruge.d uvi_tone_mix_ADVANCE		; if(NonCarry) goto ADVANCE
	xor	%r4, 1				; polar ^= 1 *delay*
	;
	xcmp	%r4, 0				; output = polar ? volume : -volume
	jrne.d	3
	ld.w	%r11, %r13			; *delay*
	ld.w	%r11, %r10			; (skip?)
	;
uvi_tone_mix_NO_ADVANCE:
	ld.h	%r9, [%r12]			; *wbuff++ += output
	add	%r9, %r11
	ld.h	[%r12]+, %r9
	;
	xsub	%r7, %r7, 1			; if(--i) goto DO
	xjrne	uvi_tone_mix_DO
	;
	xld.h	[uvi+TONE_POLAR], %r4		; uvi.tone_polar = polar /* 書き戻し */
	xld.w	[uvi+TONE_COUNT], %r5		; uvi.tone_count = count /* 書き戻し */
	;
uvi_tone_mix_EXIT:
	ret

;----------------------------------------------------------------------------

;
;	void uvi_noise_mix(short wbuff[/*UVIBUFLEN*/], int volume, int period)
;
	.global	uvi_noise_mix
uvi_noise_mix:
	xld.uh	%r4, [uvi+NOISE_LFSR ]		; lfsr  = uvi.noise_lfsr  /* 取り出し */
	xld.w	%r5, [uvi+NOISE_COUNT]		; count = uvi.noise_count /* 取り出し */
	;
	not	%r10, %r13			; %r10 = -volume
	xadd	%r10, %r10, 1
	;
	xand	%r9, %r4, 1			; %r11 = output = (lfsr & 1) ? volume : -volume
	jrne.d	3
	ld.w	%r11, %r13			; *delay*
	ld.w	%r11, %r10			; (skip?)
	;
	xld.w	%r6, NTSC_COLOR_SUBCARRIER	; %r6 = NTSC_COLOR_SUBCARRIER
	xld.w	%r7, UVIBUFLEN			; %r7 = i = UVIBUFLEN
uvi_noise_mix_DO:
	sub	%r5, %r6			; count -= NTSC_COLOR_SUBCARRIER
	xjruge	uvi_noise_mix_NO_ADVANCE	; if(NonCarry) goto NO_ADVANCE
	;
uvi_noise_mix_ADVANCE:
	ld.w	%r9, %r4			; %r9 = x = (lfsr ^ (lfsr >> 5)) & 1
	xsrl	%r9, 5
	xor	%r9, %r4
	xand	%r9, %r9, 1
	xsrl	%r4, 1				; lfsr = (lfsr >> 1) | (x << 8)
	xsll	%r9, 8
	;or	%r4, %r9			; ---------------------------+
	;					;                            |
	add	%r5, %r14			; count += period            |
	xjruge.d uvi_noise_mix_ADVANCE		; if(NonCarry) goto ADVANCE  |
	 or	%r4, %r9			; *delay* <------------------+
	;
	xand	%r9, %r4, 1			; %r11 = output = (lfsr & 1) ? volume : -volume
	jrne.d	3
	ld.w	%r11, %r13			; *delay*
	ld.w	%r11, %r10			; (skip?)
	;
uvi_noise_mix_NO_ADVANCE:
	ld.h	%r9, [%r12]			; *wbuff++ += output
	add	%r9, %r11
	ld.h	[%r12]+, %r9
	;
	xsub	%r7, %r7, 1			; if(--i) goto DO
	xjrne	uvi_noise_mix_DO
	;
	xld.h	[uvi+NOISE_LFSR ], %r4		; uvi.noise_lfsr  = lfsr  /* 書き戻し */
	xld.w	[uvi+NOISE_COUNT], %r5		; uvi.noise_count = count /* 書き戻し */
	;
uvi_noise_mix_EXIT:
	ret

;----------------------------------------------------------------------------

;
;	void uvi_volume_shift(short wbuff[/*UVIBUFLEN*/])
;
	.global uvi_volume_shift
uvi_volume_shift:
	; %r12 = wbuff
	xld.w %r13, UVIBUFLEN
	xld.w %r4, 32767
	not %r5, %r4			; -32768
uvi_volume_shift_DO:
	ld.h %r6, [%r12]
	xsll %r6, UVI_VOLUME_SHIFT
	cmp %r6, %r4
	jrle.d 3
	cmp %r6, %r5			; *delay*
	ld.w %r6, %r4			; (skip?)
	jrge.d 3
	sub %r13, 1			; *delay*
	ld.w %r6, %r5			; (skip?)
	ld.h [%r12]+, %r6
	xjrne uvi_volume_shift_DO
	ret

;****************************************************************************
;	
;****************************************************************************

#endif /*UVI_ASM*/
