;	
;	cliptiaa.s
;
;	P/ECE TIA (Television Interface Adapter) Emulator
;
;	CLiP - Common Library for P/ECE
;	Copyright (C) 2001-2005 Naoyuki Sawa
;
;	* Thu Mar 24 03:00:00 JST 2005 Naoyuki Sawa
;	- 作成開始。
;
;#define TIA_DEFINE_OFFSET
;#include "cliptiaa.h"
;/	
;/	cliptiaa.h
;/
;/	P/ECE TIA (Television Interface Adapter) Emulator
;/
;/	CLiP - Common Library for P/ECE
;/	Copyright (C) 2001-2005 Naoyuki Sawa
;/
;/	* Fri Mar 11 03:00:00 JST 2005 Naoyuki Sawa
;/	- 作成開始。
;/

;/ このファイルはC/アセンブラソース両方から参照します。
;/ C言語特有の定義を含めてはいけません。

;/ このシンボルを定義すると、アセンブラコードを使用します。
;/ このシンボルを定義しなければ、Ｃ言語コードを使用します。
;#define TIA_ASM

;* cliptiaa.s、framtiaa.sからのinclude時のみ、以下の定義を有効にします。 */
;#ifdef TIA_DEFINE_OFFSET
;****************************************************************************
;	
;****************************************************************************

;#define TIA_CLOCK	((68+160)*(3+37+192+30)*60)	; -> cliptia.h
;#define VCS_CLOCK	(TIA_CLOCK/3)			; -> cliptia.h
;#define TIABUFLEN		320			; -> cliptia.h
;#define TIA_VOLUME_SHIFT	((16-6)+1)		; -> cliptia.c
;#define SPEAKER_FREQUENCY	16000			; -> clipmisc.h

;-----------------------------------------------; typedef struct _TIA {
;#define NOW			  0		; 	int now;				/* +  0, 4: TIAクロックカウンタ (起動時からの通算) */
;#define LAST_X			  4		; 	int last_x;				/* +  4, 4: 次回更新開始X座標 (0..(  68+160   -1)) */
;#define LAST_Y			  8		; 	int last_y;				/* +  8, 4:             Y     (0..(3+37+192+30-1)) */
;#define SCAN_X			 12		; 	int scan_x;				/* + 12, 4: 現在の走査線X座標 (0..(  68+160   -1)) */
;#define SCAN_Y			 16		; 	int scan_y;				/* + 16, 4:             Y     (0..(3+37+192+30-1)) */
;#define CLUT			 20		; 	unsigned char clut[4];			/* + 20, 4: [0]=COLUP0, [1]=COLUP1, [2]=COLUPF, [3]=COLUBK */
;#define COLLISION		 24		; 	unsigned short collision;		/* + 24, 2: D01=M0-P1  (CXM0P [7]), D00=M0-P0  (CXM0P [6]) */
						; 						/*          D03=M1-P0  (CXM1P [7]), D02=M1-P1  (CXM1P [6]) */
						; 						/*          D05=P0-PF  (CXP0FB[7]), D04=P0-BL  (CXP0FB[6]) */
						; 						/*          D07=P1-PF  (CXP1FB[7]), D06=P1-BL  (CXP1FB[6]) */
						; 						/*          D09=M0-PF  (CXM0FB[7]), D08=M0-BL  (CXM0FB[6]) */
						; 						/*          D11=M1-PF  (CXM1FB[7]), D10=M1-BL  (CXM1FB[6]) */
						; 						/*          D13=BL-PF  (CXBLPF[7]), D12=unused (CXBLPF[6]) */
						; 						/*          D15=P0-P1  (CXPPMM[7]), D14=M0-M1  (CXPPMM[6]) */
;#define I4			 26		; 	unsigned char i4;			/* + 26, 1: INPT4の入力ポート状態 (1=Hi=Off,0=Lo=On) */
;#define I5			 27		; 	unsigned char i5;			/* + 27, 1: INPT5の入力ポート状態 (1=Hi=Off,0=Lo=On) */
;#define VBUFF			 28		; 	unsigned char* vbuff/*[160*192]*/;	/* + 28, 4: 仮想画面バッファ (外部定義、tia_reset()で指定) */
						; 
						;	unsigned char _resv[24];		/* + 32,24: */
						; 
						;	/*{{movable objects*/
;#define PLAYER			 56		;	TIAPLAYER player[2];			/* + 56,16: Player0, Player1 */
;#define MISSILE			 72		;	TIAMISSILE missile[2];			/* + 72, 8: Missile0, Missile1 */
;#define BALL			 80		;	TIABALL ball;				/* + 80, 8: Ball */
;#define PLAYFIELD		 88		;	TIAPLAYFIELD playfield;			/* + 88, 8: Playfield */
						;	/*}}movable objects*/
						; 
						;	/*{{AUDIO==========*/
;#define AUDIO			 96		;	TIAAUDIO audio[2];			/* + 96,32: Audio circuits */
						;	/*}}AUDIO==========*/
						; 
						; 	/*{{書き込みレジスタ*/
;#define VSYNC			128		; 	unsigned char VSYNC;			// +128, 1: $00  VSYNC   0000 00x0  vertical sync set-clear
;#define VBLANK			129		; 	unsigned char VBLANK;			// +129, 1: $01  VBLANK  xx00 00x0  vertical blank set-clear
						; 	//unsigned char WSYNC;			//          $02  WSYNC   ---- ----  wait for leading edge of horizontal blank
						; 	//unsigned char RSYNC;			//          $03  RSYNC   ---- ----  reset horizontal sync counter
;#define NUSIZ0			130		; 	unsigned char NUSIZ0;			// +130, 1: $04  NUSIZ0  00xx 0xxx  number-size player-missile 0
;#define NUSIZ1			131		; 	unsigned char NUSIZ1;			// +131, 1: $05  NUSIZ1  00xx 0xxx  number-size player-missile 1
;#define COLUP0			132		; 	unsigned char COLUP0;			// +132, 1: $06  COLUP0  xxxx xxx0  color-lum player 0
;#define COLUP1			133		; 	unsigned char COLUP1;			// +133, 1: $07  COLUP1  xxxx xxx0  color-lum player 1
;#define COLUPF			134		; 	unsigned char COLUPF;			// +134, 1: $08  COLUPF  xxxx xxx0  color-lum playfield
;#define COLUBK			135		; 	unsigned char COLUBK;			// +135, 1: $09  COLUBK  xxxx xxx0  color-lum background
;#define CTRLPF			136		; 	unsigned char CTRLPF;			// +136, 1: $0A  CTRLPF  00xx 0xxx  control playfield ball size & collisions
;#define REFP0			137		; 	unsigned char REFP0;			// +137, 1: $0B  REFP0   0000 x000  reflect player 0
;#define REFP1			138		; 	unsigned char REFP1;			// +138, 1: $0C  REFP1   0000 x000  reflect player 1
;#define PF0			139		; 	unsigned char PF0;			// +139, 1: $0D  PF0     xxxx 0000  playfield register byte 0
;#define PF1			140		; 	unsigned char PF1;			// +140, 1: $0E  PF1     xxxx xxxx  playfield register byte 1
;#define PF2			141		; 	unsigned char PF2;			// +141, 1: $0F  PF2     xxxx xxxx  playfield register byte 2
						; 	//unsigned char RESP0;			//          $10  RESP0   ---- ----  reset player 0
						; 	//unsigned char RESP1;			//          $11  RESP1   ---- ----  reset player 1
						; 	//unsigned char RESM0;			//          $12  RESM0   ---- ----  reset missile 0
						; 	//unsigned char RESM1;			//          $13  RESM1   ---- ----  reset missile 1
						; 	//unsigned char RESBL;			//          $14  RESBL   ---- ----  reset ball
;#define AUDC0			142		; 	unsigned char AUDC0;			// +142, 1: $15  AUDC0   0000 xxxx  audio control 0
;#define AUDC1			143		; 	unsigned char AUDC1;			// +143, 1: $16  AUDC1   0000 xxxx  audio control 1
;#define AUDF0			144		; 	unsigned char AUDF0;			// +144, 1: $17  AUDF0   000x xxxx  audio frequency 0
;#define AUDF1			145		; 	unsigned char AUDF1;			// +145, 1: $18  AUDF1   000x xxxx  audio frequency 1
;#define AUDV0			146		; 	unsigned char AUDV0;			// +146, 1: $19  AUDV0   0000 xxxx  audio volume 0
;#define AUDV1			147		; 	unsigned char AUDV1;			// +147, 1: $1A  AUDV1   0000 xxxx  audio volume 1
						; 	//unsigned char GRP0;			//          $1B  GRP0    xxxx xxxx  graphics player 0
						; 	//unsigned char GRP1;			//          $1C  GRP1    xxxx xxxx  graphics player 1
;#define ENAM0			148		; 	unsigned char ENAM0;			// +148, 1: $1D  ENAM0   0000 00x0  graphics (enable) missile 0
;#define ENAM1			149		; 	unsigned char ENAM1;			// +149, 1: $1E  ENAM1   0000 00x0  graphics (enable) missile 1
;#define ENABL			150		; 	unsigned char ENABL;			// +150, 1: $1F  ENABL   0000 00x0  graphics (enable) ball
;#define HMP0			151		; 	unsigned char HMP0;			// +151, 1: $20  HMP0    xxxx 0000  horizontal motion player 0
;#define HMP1			152		; 	unsigned char HMP1;			// +152, 1: $21  HMP1    xxxx 0000  horizontal motion player 1
;#define HMM0			153		; 	unsigned char HMM0;			// +153, 1: $22  HMM0    xxxx 0000  horizontal motion missile 0
;#define HMM1			154		; 	unsigned char HMM1;			// +154, 1: $23  HMM1    xxxx 0000  horizontal motion missile 1
;#define HMBL			155		; 	unsigned char HMBL;			// +155, 1: $24  HMBL    xxxx 0000  horizontal motion ball
						; 	//unsigned char VDELP0;			//          $25  VDELP0  0000 000x  vertical delay player 0
						; 	//unsigned char VDELP1;			//          $26  VDELP1  0000 000x  vertical delay player 1
						; 	//unsigned char VDELBL;			//          $27  VDELBL  0000 000x  vertical delay ball
;#define RESMP0			156		; 	unsigned char RESMP0;			// +156, 1: $28  RESMP0  0000 00x0  reset missile 0 to player 0
;#define RESMP1			157		; 	unsigned char RESMP1;			// +157, 1: $29  RESMP1  0000 00x0  reset missile 1 to player 1
						; 	//unsigned char HMOVE;			//          $2A  HMOVE   ---- ----  apply horizontal motion
						; 	//unsigned char HMCLR;			//          $2B  HMCLR   ---- ----  clear horizontal motion registers
						; 	//unsigned char CXCLR;			//          $2C  CXCLR   ---- ----  clear collision latches
						; 	/*}}書き込みレジスタ*/
						; 
						; 	/*{{読み出しレジスタ*/
						; 	//unsigned char CXM0P;			//          $0   CXM0P   xx00 0000  read collision M0-P1 M0-P0
						; 	//unsigned char CXM1P;			//          $1   CXM1P   xx00 0000  read collision M1-P0 M1-P1
						; 	//unsigned char CXP0FB;			//          $2   CXP0FB  xx00 0000  read collision P0-PF P0-BL
						; 	//unsigned char CXP1FB;			//          $3   CXP1FB  xx00 0000  read collision P1-PF P1-BL
						; 	//unsigned char CXM0FB;			//          $4   CXM0FB  xx00 0000  read collision M0-PF M0-BL
						; 	//unsigned char CXM1FB;			//          $5   CXM1FB  xx00 0000  read collision M1-PF M1-BL
						; 	//unsigned char CXBLPF;			//          $6   CXBLPF  x000 0000  read collision BL-PF unused
						; 	//unsigned char CXPPMM;			//          $7   CXPPMM  xx00 0000  read collision P0-P1 M0-M1
;#define INPT0			158		; 	unsigned char INPT0;			// +158, 1: $8   INPT0   x000 0000  read pot port
;#define INPT1			159		; 	unsigned char INPT1;			// +159, 1: $9   INPT1   x000 0000  read pot port
;#define INPT2			160		; 	unsigned char INPT2;			// +160, 1: $A   INPT2   x000 0000  read pot port
;#define INPT3			161		; 	unsigned char INPT3;			// +161, 1: $B   INPT3   x000 0000  read pot port
;#define INPT4			162		; 	unsigned char INPT4;			// +162, 1: $C   INPT4   x000 0000  read input
;#define INPT5			163		; 	unsigned char INPT5;			// +163, 1: $D   INPT5   x000 0000  read input
						; 	/*}}読み出しレジスタ*/
;-----------------------------------------------; } TIA;					// =164
						; #define SIZEOF_TIA				    164 /* tia_reset()時にサイズを検査します */

;-----------------------------------------------; typedef struct _TIAPLAYER {
;#define PLAYER0_POSITION	(PLAYER+0+0)	; 	unsigned char position;			/* +0,1: 0..159 */
;#define PLAYER0_SIZE		(PLAYER+0+1)	; 	unsigned char size;			/* +1,1: 0=x, 1=x_x, 2=x___x, 3=x_x_x, 4=x_______x, 5=XX, 6=x___x___x, 7=XXXX */
;#define PLAYER0_REFLECT		(PLAYER+0+2)	; 	unsigned char reflect;			/* +2,1: 0=no reflect, 1=reflect */
;#define PLAYER0_DELAY		(PLAYER+0+3)	; 	unsigned char delay;			/* +3,1: 0=no delay, 1=delay */
;#define PLAYER0_GRAPHICS	(PLAYER+0+4)	; 	unsigned char graphics[2];		/* +4,2: 8bit graphics ([0]=no delay, [1]=delay) */
						; 	unsigned char _resv[2];			/* +6,2: (予約) */
;-----------------------------------------------; } TIAPLAYER;					/* =8 */

;-----------------------------------------------; typedef struct _TIAPLAYER {
;#define PLAYER1_POSITION	(PLAYER+8+0)	; 	unsigned char position;			/* +0,1: 0..159 */
;#define PLAYER1_SIZE		(PLAYER+8+1)	; 	unsigned char size;			/* +1,1: 0=x, 1=x_x, 2=x___x, 3=x_x_x, 4=x_______x, 5=XX, 6=x___x___x, 7=XXXX */
;#define PLAYER1_REFLECT		(PLAYER+8+2)	; 	unsigned char reflect;			/* +2,1: 0=no reflect, 1=reflect */
;#define PLAYER1_DELAY		(PLAYER+8+3)	; 	unsigned char delay;			/* +3,1: 0=no delay, 1=delay */
;#define PLAYER1_GRAPHICS	(PLAYER+8+4)	; 	unsigned char graphics[2];		/* +4,2: 8bit graphics ([0]=no delay, [1]=delay) */
						; 	unsigned char _resv[2];			/* +6,2: (予約) */
;-----------------------------------------------; } TIAPLAYER;					/* =8 */

;-----------------------------------------------; typedef struct _TIAMISSILE {
;#define MISSILE0_POSITION	(MISSILE+0+0)	; 	unsigned char position;			/* +0,1: 0..159 */
;#define MISSILE0_SIZE		(MISSILE+0+1)	; 	unsigned char size;			/* +1,1: 0=1clock, 1=2clock, 2=4clock, 3=8clock */
;#define MISSILE0_RESET		(MISSILE+0+2)	; 	unsigned char reset;			/* +2,1: 0=no missile-player reset, 1=missile-player reset */
;#define MISSILE0_GRAPHICS	(MISSILE+0+3)	; 	unsigned char graphics;			/* +3,1: 0=disable, 1=enable */
;-----------------------------------------------; } TIAMISSILE;					/* =4 */

;-----------------------------------------------; typedef struct _TIAMISSILE {
;#define MISSILE1_POSITION	(MISSILE+4+0)	; 	unsigned char position;			/* +0,1: 0..159 */
;#define MISSILE1_SIZE		(MISSILE+4+1)	; 	unsigned char size;			/* +1,1: 0=1clock, 1=2clock, 2=4clock, 3=8clock */
;#define MISSILE1_RESET		(MISSILE+4+2)	; 	unsigned char reset;			/* +2,1: 0=no missile-player reset, 1=missile-player reset */
;#define MISSILE1_GRAPHICS	(MISSILE+4+3)	; 	unsigned char graphics;			/* +3,1: 0=disable, 1=enable */
;-----------------------------------------------; } TIAMISSILE;					/* =4 */

;-----------------------------------------------; typedef struct _TIABALL {
;#define BALL_POSITION		(BALL+0)	; 	unsigned char position;			/* +0,1: 0..159 */
;#define BALL_SIZE		(BALL+1)	; 	unsigned char size;			/* +1,1: 0=1clock, 1=2clock, 2=4clock, 3=8clock */
;#define BALL_DELAY		(BALL+2)	; 	unsigned char delay;			/* +2,1: 0=no delay, 1=delay */
;#define BALL_GRAPHICS		(BALL+3)	; 	unsigned char graphics[2];		/* +3,2: 0=disable, 1=enable ([0]=no delay, [1]=delay) */
						; 	unsigned char _resv[3];			/* +5,3: (予約) */
;-----------------------------------------------; } TIABALL;					/* =8 */

;-----------------------------------------------; typedef struct _TIAPLAYFIELD {
;#define PLAYFIELD_REFLECT	(PLAYFIELD+0)	; 	unsigned char reflect;			/* +0,1: 0=no relfect, 1=reflect */
						; 	unsigned char _resv[3];			/* +1,3: (予約) */
;#define PLAYFIELD_GRAPHICS	(PLAYFIELD+4)	; 	unsigned int graphics;			/* +4,4: 20bit graphics */
;-----------------------------------------------; } TIAPLAYFIELD;				/* =8 */

;-----------------------------------------------; typedef struct _TIAAUDIO {
;#define AUDIO_VOLUME		 0		; 	unsigned char volume;			/* + 0,1: lowest:0..15:highest */
;#define AUDIO_FREQUENCY		 1		; 	unsigned char frequency;		/* + 1,1: frequency divider 1..32 */
						; 	//
;#define AUDIO_POLAR		 2		; 	unsigned char  polar;			/* + 2,1: 0:minus or 1:plus */
;#define AUDIO_DIV31		 3		; 	unsigned char  div31;			/* + 3,1: 30..0, 0or13->pluse */
;#define AUDIO_COUNT		 4		; 	         int   count;			/* + 4,4: frequency counter */
;#define AUDIO_LFSR9		 8		; 	unsigned short lfsr9;			/* + 8,2: 9-bit LFSR (tap=0,5) */
;#define AUDIO_LFSR5		10		; 	unsigned char  lfsr5;			/* +10,1: 5-bit LFSR (tap=0,3) */
;#define AUDIO_LFSR4		11		; 	unsigned char  lfsr4;			/* +11,1: 4-bit LFSR (tap=0,1) */
						; 	//
						; 	unsigned char _resv[4];			/* +12,4: (予約) */
;-----------------------------------------------; } TIAAUDIO;					/* =16 */

;****************************************************************************
;	
;****************************************************************************
;#endif /*TIA_DEFINE_OFFSET*/
;#ifdef TIA_ASM

	.code
	.align	1

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

;			       3210
;	4-bit LFSR:	+----> xxxx -> output
;			|        ||
;			+- xor <-++
;
;#macro	UPDATE_LFSR4	$1
;	ld.w	%r9, $1				; x = (lfsr4 ^ (lfsr4 >> 1)) & 1
;	srl	%r9, 1
;	xor	%r9, $1
;	xand	%r9, %r9, 1
;	xsrl	$1, 1				; lfsr4 = (lfsr4 >> 1) | (x << (4 - 1))
;	xsll	%r9, (4-1)
;	or	$1, %r9
;#endm

;			        43210
;	5-bit LFSR:	+-----> xxxxx -> output
;			|        |  |
;			+- xor <-+--+
;
;#macro	UPDATE_LFSR5	$1
;	ld.w	%r9, $1				; x = (LFSR5 ^ (LFSR5 >> 3)) & 1
;	srl	%r9, 3
;	xor	%r9, $1
;	xand	%r9, %r9, 1
;	xsrl	$1, 1				; LFSR5 = (LFSR5 >> 1) | (x << (5 - 1))
;	xsll	%r9, (5-1)
;	or	$1, %r9
;#endm

;			      876543210
;	5-bit LFSR:	+---> xxxxxxxxx -> output
;			|        |    |
;			+- xor <-+----+
;
;#macro	UPDATE_LFSR9	$1
;	ld.w	%r9, $1				; x = (LFSR9 ^ (LFSR9 >> 5)) & 1
;	srl	%r9, 5
;	xor	%r9, $1
;	xand	%r9, %r9, 1
;	xsrl	$1, 1				; LFSR9 = (LFSR9 >> 1) | (x << (9 - 1))
;	xsll	%r9, (9-1)
;	or	$1, %r9
;#endm

;			         0
;	Polar:		+------> x -> output
;			|        |
;			+- not <-+
;
;#macro	UPDATE_POLAR	$1
;	xxor	$1, $1, 1
;#endm

;			   0
;	LFSR/Polar:	...x -> output +-> 1: +volume
;			               +-> 0: -volume
;
;#macro	UPDATE_OUTPUT	$1, $2, $3		; $1=lfsr/polar, $2=output, $3=volume
;	xand	%r9, $1, 1			; output = (lfsr/polar & 1) ? volume : -volume
;	jrne.d	4
;	ld.w	$2, $3				; *delay*
;	not	$2, $2				; (skip?)
;	add	$2, 1				; (skip?)
;#endm

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

;
;	30KHz/Freq pulse ----------------> Polar toggle ->
;
	.global	tia_audio_mix4
tia_audio_mix4:
	ext	0x1eb		; 	xld.w	%r14, 0x7ad0
	ld.w	%r14,0x10
	jp	tia_audio_mix4C	; 	xjp	tia_audio_mix4C

;
;	10KHz/Freq pulse ----------------> Polar toggle ->
;
	.global	tia_audio_mixC
tia_audio_mixC:
	ext	0xa3		; 	xld.w	%r14, 0x28f0
	ld.w	%r14,0x30
	jp	tia_audio_mix4C	; 	xjp	tia_audio_mix4C

;
;	clock/Freq pulse ----------------> Polar toggle ->
;
tia_audio_mix4C:
	ld.ub	%r10,[%r12]	; 	xld.ub	%r10, [%r12+0x0]	; %r10 = volume = audio->volume
	cmp	%r10, 0				; !INTERLOCK!
	jreq	tia_audio_mix4C_EXIT	; 	xjreq	tia_audio_mix4C_EXIT		; if(!volume) goto EXIT
	;
	ext	0x1		; 	xld.ub	%r11, [%r12+0x1]	; %r11 = period = SPEAKER_FREQUENCY * audio->frequency
	ld.ub	%r11,[%r12]
	ext	0xfa		; 	xld.w	%r9, 16000		; *anti-interlock*
	ld.w	%r9,0x0
	mlt.h	%r11, %r9			; (16000×(1..32)なので、mlt.hで充分)
	ld.w	%r11, %alr
	;
	ext	0x4		; 	xld.w	%r4, [%r12+0x4]		; %r4 = count = audio->count /* 取り出し */
	ld.w	%r4,[%r12]
	ext	0x2		; 	xld.ub	%r6, [%r12+0x2]		; %r6 = polar = audio->polar /* 取り出し */
	ld.ub	%r6,[%r12]
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		; Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
	ext	0x5		; 	xld.w	%r15, 320			; %r15 = i = TIABUFLEN
	ld.w	%r15,0x0
tia_audio_mix4C_DO:				; do {
	sub	%r4, %r14			;   count -= clock
	jruge	tia_audio_mix4C_NO_ADVANCE	; 	xjruge	tia_audio_mix4C_NO_ADVANCE	;   if(count < 0) { /*!NonCarry*/
tia_audio_mix4C_ADVANCE_DO:			;     do {
	xor	%r6,0x1		; 	xxor	%r6, %r6, 1	; 	UPDATE_POLAR	%r6			;         Update polar
	add	%r4, %r11			;     } while((count += period) < 0) /*NonCarry*/
	jruge	tia_audio_mix4C_ADVANCE_DO	; 	xjruge	tia_audio_mix4C_ADVANCE_DO
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		;     Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
tia_audio_mix4C_NO_ADVANCE:			;   }
	ld.h	%r9, [%r13]			;   *wbuff++ += output
	add	%r9, %r7
	ld.h	[%r13]+, %r9
	;
	sub	%r15,0x1	; 	xsub	%r15, %r15, 1			; } while(--i)
	jrne	tia_audio_mix4C_DO	; 	xjrne	tia_audio_mix4C_DO
	;
	ext	0x4		; 	xld.w	[%r12+0x4], %r4		; audio->count = count /* 書き戻し */
	ld.w	[%r12],%r4
	ext	0x2		; 	xld.b	[%r12+0x2], %r6		; audio->polar = polar /* 書き戻し */
	ld.b	[%r12],%r6
tia_audio_mix4C_EXIT:
	ret

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

;
;	30KHz/Freq pulse -> Div31 pulse -> Polar toggle ->
;
	.global	tia_audio_mix6
tia_audio_mix6:
	ext	0x1eb		; 	xld.w	%r14, 0x7ad0
	ld.w	%r14,0x10
	jp	tia_audio_mix6E	; 	xjp	tia_audio_mix6E

;
;	10KHz/Freq pulse -> Div31 pulse -> Polar toggle ->
;
	.global	tia_audio_mixE
tia_audio_mixE:
	ext	0xa3		; 	xld.w	%r14, 0x28f0
	ld.w	%r14,0x30
	jp	tia_audio_mix6E	; 	xjp	tia_audio_mix6E

;
;	clock/Freq pulse -> Div31 pulse -> Polar toggle ->
;
tia_audio_mix6E:
	ld.ub	%r10,[%r12]	; 	xld.ub	%r10, [%r12+0x0]	; %r10 = volume = audio->volume
	cmp	%r10, 0				; !INTERLOCK!
	jreq	tia_audio_mix6E_EXIT	; 	xjreq	tia_audio_mix6E_EXIT		; if(!volume) goto EXIT
	;
	ext	0x1		; 	xld.ub	%r11, [%r12+0x1]	; %r11 = period = SPEAKER_FREQUENCY * audio->frequency
	ld.ub	%r11,[%r12]
	ext	0xfa		; 	xld.w	%r9, 16000		; *anti-interlock*
	ld.w	%r9,0x0
	mlt.h	%r11, %r9			; (16000×(1..32)なので、mlt.hで充分)
	ld.w	%r11, %alr
	;
	ext	0x4		; 	xld.w	%r4, [%r12+0x4]		; %r4 = count = audio->count /* 取り出し */
	ld.w	%r4,[%r12]
	ext	0x3		; 	xld.ub	%r5, [%r12+0x3]		; %r5 = div31 = audio->div31 /* 取り出し */
	ld.ub	%r5,[%r12]
	ext	0x2		; 	xld.ub	%r6, [%r12+0x2]		; %r6 = polar = audio->polar /* 取り出し */
	ld.ub	%r6,[%r12]
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		; Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
	ext	0x5		; 	xld.w	%r15, 320			; %r15 = i = TIABUFLEN
	ld.w	%r15,0x0
tia_audio_mix6E_DO:				; do {
	sub	%r4, %r14			;   count -= clock
	jruge	tia_audio_mix6E_NO_ADVANCE	; 	xjruge	tia_audio_mix6E_NO_ADVANCE	;   if(count < 0) { /*!NonCarry*/
tia_audio_mix6E_ADVANCE_DO:			;     do {
	sub	%r5,0x1		; 	xsub	%r5, %r5, 1			;       if(--div31 < 0) div31 += 31
	jruge	2
	add	%r5, 31				;       (skip?)
	jreq	2
	cmp	%r5, 13				;       (skip?)
	jrne	tia_audio_mix6E_ADVANCE_LOOP	; 	xjrne	tia_audio_mix6E_ADVANCE_LOOP	;       if(div31 == 0 || div31 == 13) {
	xor	%r6,0x1		; 	xxor	%r6, %r6, 1	; 	UPDATE_POLAR	%r6			;         Update polar
tia_audio_mix6E_ADVANCE_LOOP:			;       }
	add	%r4, %r11			;     } while((count += period) < 0) /*NonCarry*/
	jruge	tia_audio_mix6E_ADVANCE_DO	; 	xjruge	tia_audio_mix6E_ADVANCE_DO
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		;     Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
tia_audio_mix6E_NO_ADVANCE:			;   }
	ld.h	%r9, [%r13]			;   *wbuff++ += output
	add	%r9, %r7
	ld.h	[%r13]+, %r9
	;
	sub	%r15,0x1	; 	xsub	%r15, %r15, 1			; } while(--i)
	jrne	tia_audio_mix6E_DO	; 	xjrne	tia_audio_mix6E_DO
	;
	ext	0x4		; 	xld.w	[%r12+0x4], %r4		; audio->count = count /* 書き戻し */
	ld.w	[%r12],%r4
	ext	0x3		; 	xld.b	[%r12+0x3], %r5		; audio->div31 = div31 /* 書き戻し */
	ld.b	[%r12],%r5
	ext	0x2		; 	xld.b	[%r12+0x2], %r6		; audio->polar = polar /* 書き戻し */
	ld.b	[%r12],%r6
	;
tia_audio_mix6E_EXIT:
	ret

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

;
;	30KHz/Freq pulse -> Poly5 pulse -> Polar toggle ->
;
	.global	tia_audio_mix7
tia_audio_mix7:
	ext	0x1eb		; 	xld.w	%r14, 0x7ad0
	ld.w	%r14,0x10
	jp	tia_audio_mix7F	; 	xjp	tia_audio_mix7F

;
;	10KHz/Freq pulse -> Poly5 pulse -> Polar toggle ->
;
	.global	tia_audio_mixF
tia_audio_mixF:
	ext	0xa3		; 	xld.w	%r14, 0x28f0
	ld.w	%r14,0x30
	jp	tia_audio_mix7F	; 	xjp	tia_audio_mix7F

;
;	clock/Freq pulse -> Poly5 pulse -> Polar toggle ->
;
tia_audio_mix7F:
	ld.ub	%r10,[%r12]	; 	xld.ub	%r10, [%r12+0x0]	; %r10 = volume = audio->volume
	cmp	%r10, 0				; !INTERLOCK!
	jreq	tia_audio_mix7F_EXIT	; 	xjreq	tia_audio_mix7F_EXIT		; if(!volume) goto EXIT
	;
	ext	0x1		; 	xld.ub	%r11, [%r12+0x1]	; %r11 = period = SPEAKER_FREQUENCY * audio->frequency
	ld.ub	%r11,[%r12]
	ext	0xfa		; 	xld.w	%r9, 16000		; *anti-interlock*
	ld.w	%r9,0x0
	mlt.h	%r11, %r9			; (16000×(1..32)なので、mlt.hで充分)
	ld.w	%r11, %alr
	;
	ext	0x4		; 	xld.w	%r4, [%r12+0x4]		; %r4 = count = audio->count /* 取り出し */
	ld.w	%r4,[%r12]
	ext	0xa		; 	xld.ub	%r5, [%r12+0xa]		; %r5 = lfsr5 = audio->lfsr5 /* 取り出し */
	ld.ub	%r5,[%r12]
	ext	0x2		; 	xld.ub	%r6, [%r12+0x2]		; %r6 = polar = audio->polar /* 取り出し */
	ld.ub	%r6,[%r12]
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		; Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
	ext	0x5		; 	xld.w	%r15, 320			; %r15 = i = TIABUFLEN
	ld.w	%r15,0x0
tia_audio_mix7F_DO:				; do {
	sub	%r4, %r14			;   count -= clock
	jruge	tia_audio_mix7F_NO_ADVANCE	; 	xjruge	tia_audio_mix7F_NO_ADVANCE	;   if(count < 0) { /*!NonCarry*/
tia_audio_mix7F_ADVANCE_DO:			;     do {
	ld.w	%r9, %r5				; x = (LFSR5 ^ (LFSR5 >> 3)) & 1	; 	UPDATE_LFSR5	%r5			;       Update LFSR
	srl	%r9, 3
	xor	%r9, %r5
	and	%r9,0x1		; 	xand	%r9, %r9, 1
	srl	%r5,0x1		; 	xsrl	%r5, 1				; LFSR5 = (LFSR5 >> 1) | (x << (5 - 1))
	sll	%r9,0x4		; 	xsll	%r9, 0x4
	or	%r5, %r9
	ext	0x1		; 	xand	%r9, %r5, 1			;       if(lfsr5 & 1) {
	and	%r9,%r5
	jreq	tia_audio_mix7F_ADVANCE_LOOP	; 	xjreq	tia_audio_mix7F_ADVANCE_LOOP
	xor	%r6,0x1		; 	xxor	%r6, %r6, 1	; 	UPDATE_POLAR	%r6			;         Update polar
tia_audio_mix7F_ADVANCE_LOOP:			;       }
	add	%r4, %r11			;     } while((count += period) < 0) /*NonCarry*/
	jruge	tia_audio_mix7F_ADVANCE_DO	; 	xjruge	tia_audio_mix7F_ADVANCE_DO
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		;     Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
tia_audio_mix7F_NO_ADVANCE:			;   }
	ld.h	%r9, [%r13]			;   *wbuff++ += output
	add	%r9, %r7
	ld.h	[%r13]+, %r9
	;
	sub	%r15,0x1	; 	xsub	%r15, %r15, 1			; } while(--i)
	jrne	tia_audio_mix7F_DO	; 	xjrne	tia_audio_mix7F_DO
	;
	ext	0x4		; 	xld.w	%r4, [%r12+0x4]		; %r4 = audio->count = count /* 書き戻し */
	ld.w	%r4,[%r12]
	ext	0xa		; 	xld.b	%r5, [%r12+0xa]		; %r5 = audio->lfsr5 = lfsr5 /* 書き戻し */
	ld.b	%r5,[%r12]
	ext	0x2		; 	xld.b	%r6, [%r12+0x2]		; %r6 = audio->polar = polar /* 書き戻し */
	ld.b	%r6,[%r12]
	;
tia_audio_mix7F_EXIT:
	ret

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

;
;	                                              1 ->
;
	.global	tia_audio_mix0
tia_audio_mix0:
	ld.ub	%r10,[%r12]	; 	xld.ub	%r10, [%r12+0x0]	; %r10 = volume = audio->volume
	cmp	%r10, 0				; !INTERLOCK!
	jreq	tia_audio_mix0_EXIT	; 	xjreq	tia_audio_mix0_EXIT		; if(!volume) goto EXIT
	;
	ext	0x1eb		; 	xld.w	%r14, 0x7ad0		; %r14 = clock = TIA_CLOCK / 114
	ld.w	%r14,0x10
	ext	0x5		; 	xld.w	%r15, 320			; %r15 = i = TIABUFLEN
	ld.w	%r15,0x0
tia_audio_mix0_DO:				; do {
	ld.h	%r9, [%r13]			;   *wbuff++ += volume
	add	%r9, %r10
	ld.h	[%r13]+, %r9
	;
	sub	%r15,0x1	; 	xsub	%r15, %r15, 1			; } while(--i)
	jrne	tia_audio_mix0_DO	; 	xjrne	tia_audio_mix0_DO
tia_audio_mix0_EXIT:
	ret

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

;
;	30KHz/Freq pulse ----------------> Poly4 output ->
;
	.global	tia_audio_mix1
tia_audio_mix1:
	ld.ub	%r10,[%r12]	; 	xld.ub	%r10, [%r12+0x0]	; %r10 = volume = audio->volume
	cmp	%r10, 0				; !INTERLOCK!
	jreq	tia_audio_mix1_EXIT	; 	xjreq	tia_audio_mix1_EXIT		; if(!volume) goto EXIT
	;
	ext	0x1		; 	xld.ub	%r11, [%r12+0x1]	; %r11 = period = SPEAKER_FREQUENCY * audio->frequency
	ld.ub	%r11,[%r12]
	ext	0xfa		; 	xld.w	%r9, 16000		; *anti-interlock*
	ld.w	%r9,0x0
	mlt.h	%r11, %r9			; (16000×(1..32)なので、mlt.hで充分)
	ld.w	%r11, %alr
	;
	ext	0x4		; 	xld.w	%r4, [%r12+0x4]		; %r4 = count = audio->count /* 取り出し */
	ld.w	%r4,[%r12]
	ext	0xb		; 	xld.ub	%r6, [%r12+0xb]		; %r6 = lfsr4 = audio->lfsr4 /* 取り出し */
	ld.ub	%r6,[%r12]
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		; Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
	ext	0x1eb		; 	xld.w	%r14, 0x7ad0		; %r14 = clock = TIA_CLOCK / 114
	ld.w	%r14,0x10
	ext	0x5		; 	xld.w	%r15, 320			; %r15 = i = TIABUFLEN
	ld.w	%r15,0x0
tia_audio_mix1_DO:				; do {
	sub	%r4, %r14			;   count -= clock
	jruge	tia_audio_mix1_NO_ADVANCE	; 	xjruge	tia_audio_mix1_NO_ADVANCE	;   if(count < 0) { /*!NonCarry*/
tia_audio_mix1_ADVANCE_DO:			;     do {
	ld.w	%r9, %r6				; x = (lfsr4 ^ (lfsr4 >> 1)) & 1	; 	UPDATE_LFSR4	%r6			;         Update LFSR
	srl	%r9, 1
	xor	%r9, %r6
	and	%r9,0x1		; 	xand	%r9, %r9, 1
	srl	%r6,0x1		; 	xsrl	%r6, 1				; lfsr4 = (lfsr4 >> 1) | (x << (4 - 1))
	sll	%r9,0x3		; 	xsll	%r9, 0x3
	or	%r6, %r9
	add	%r4, %r11			;     } while((count += period) < 0) /*NonCarry*/
	jruge	tia_audio_mix1_ADVANCE_DO	; 	xjruge	tia_audio_mix1_ADVANCE_DO
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		;     Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
tia_audio_mix1_NO_ADVANCE:			;   }
	ld.h	%r9, [%r13]			;   *wbuff++ += output
	add	%r9, %r7
	ld.h	[%r13]+, %r9
	;
	sub	%r15,0x1	; 	xsub	%r15, %r15, 1			; } while(--i)
	jrne	tia_audio_mix1_DO	; 	xjrne	tia_audio_mix1_DO
	;
	ext	0x4		; 	xld.w	[%r12+0x4], %r4		; audio->count = count /* 書き戻し */
	ld.w	[%r12],%r4
	ext	0xb		; 	xld.b	[%r12+0xb], %r6		; audio->lfsr4 = lfsr4 /* 書き戻し */
	ld.b	[%r12],%r6
tia_audio_mix1_EXIT:
	ret

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

;
;	30KHz/Freq pulse -> Div31 pulse -> Poly4 output ->
;
	.global	tia_audio_mix2
tia_audio_mix2:
	ld.ub	%r10,[%r12]	; 	xld.ub	%r10, [%r12+0x0]	; %r10 = volume = audio->volume
	cmp	%r10, 0				; !INTERLOCK!
	jreq	tia_audio_mix2_EXIT	; 	xjreq	tia_audio_mix2_EXIT		; if(!volume) goto EXIT
	;
	ext	0x1		; 	xld.ub	%r11, [%r12+0x1]	; %r11 = period = SPEAKER_FREQUENCY * audio->frequency
	ld.ub	%r11,[%r12]
	ext	0xfa		; 	xld.w	%r9, 16000		; *anti-interlock*
	ld.w	%r9,0x0
	mlt.h	%r11, %r9			; (16000×(1..32)なので、mlt.hで充分)
	ld.w	%r11, %alr
	;
	ext	0x4		; 	xld.w	%r4, [%r12+0x4]		; %r4 = count = audio->count /* 取り出し */
	ld.w	%r4,[%r12]
	ext	0x3		; 	xld.ub	%r5, [%r12+0x3]		; %r5 = div31 = audio->div31 /* 取り出し */
	ld.ub	%r5,[%r12]
	ext	0xb		; 	xld.ub	%r6, [%r12+0xb]		; %r6 = lfsr4 = audio->lfsr4 /* 取り出し */
	ld.ub	%r6,[%r12]
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		; Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
	ext	0x1eb		; 	xld.w	%r14, 0x7ad0		; %r14 = clock = TIA_CLOCK / 114
	ld.w	%r14,0x10
	ext	0x5		; 	xld.w	%r15, 320			; %r15 = i = TIABUFLEN
	ld.w	%r15,0x0
tia_audio_mix2_DO:				; do {
	sub	%r4, %r14			;   count -= clock
	jruge	tia_audio_mix2_NO_ADVANCE	; 	xjruge	tia_audio_mix2_NO_ADVANCE	;   if(count < 0) { /*!NonCarry*/
tia_audio_mix2_ADVANCE_DO:			;     do {
	sub	%r5,0x1		; 	xsub	%r5, %r5, 1			;       if(--div31 < 0) div31 += 31
	jruge	2
	add	%r5, 31				;       (skip?)
	jreq	2
	cmp	%r5, 13				;       (skip?)
	jrne	tia_audio_mix2_ADVANCE_LOOP	; 	xjrne	tia_audio_mix2_ADVANCE_LOOP	;       if(div31 == 0 || div31 == 13) {
	ld.w	%r9, %r6				; x = (lfsr4 ^ (lfsr4 >> 1)) & 1	; 	UPDATE_LFSR4	%r6			;         Update LFSR
	srl	%r9, 1
	xor	%r9, %r6
	and	%r9,0x1		; 	xand	%r9, %r9, 1
	srl	%r6,0x1		; 	xsrl	%r6, 1				; lfsr4 = (lfsr4 >> 1) | (x << (4 - 1))
	sll	%r9,0x3		; 	xsll	%r9, 0x3
	or	%r6, %r9
tia_audio_mix2_ADVANCE_LOOP:			;       }
	add	%r4, %r11			;     } while((count += period) < 0) /*NonCarry*/
	jruge	tia_audio_mix2_ADVANCE_DO	; 	xjruge	tia_audio_mix2_ADVANCE_DO
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		;     Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
tia_audio_mix2_NO_ADVANCE:			;   }
	ld.h	%r9, [%r13]			;   *wbuff++ += output
	add	%r9, %r7
	ld.h	[%r13]+, %r9
	;
	sub	%r15,0x1	; 	xsub	%r15, %r15, 1			; } while(--i)
	jrne	tia_audio_mix2_DO	; 	xjrne	tia_audio_mix2_DO
	;
	ext	0x4		; 	xld.w	[%r12+0x4], %r4		; audio->count = count /* 書き戻し */
	ld.w	[%r12],%r4
	ext	0x3		; 	xld.b	[%r12+0x3], %r5		; audio->div31 = div31 /* 書き戻し */
	ld.b	[%r12],%r5
	ext	0xb		; 	xld.b	[%r12+0xb], %r6		; audio->lfsr4 = lfsr4 /* 書き戻し */
	ld.b	[%r12],%r6
tia_audio_mix2_EXIT:
	ret

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

;
;	30KHz/Freq pulse -> Poly5 pulse -> Poly4 output ->
;
	.global	tia_audio_mix3
tia_audio_mix3:
	ld.ub	%r10,[%r12]	; 	xld.ub	%r10, [%r12+0x0]	; %r10 = volume = audio->volume
	cmp	%r10, 0				; !INTERLOCK!
	jreq	tia_audio_mix3_EXIT	; 	xjreq	tia_audio_mix3_EXIT		; if(!volume) goto EXIT
	;
	ext	0x1		; 	xld.ub	%r11, [%r12+0x1]	; %r11 = period = SPEAKER_FREQUENCY * audio->frequency
	ld.ub	%r11,[%r12]
	ext	0xfa		; 	xld.w	%r9, 16000		; *anti-interlock*
	ld.w	%r9,0x0
	mlt.h	%r11, %r9			; (16000×(1..32)なので、mlt.hで充分)
	ld.w	%r11, %alr
	;
	ext	0x4		; 	xld.w	%r4, [%r12+0x4]		; %r4 = count = audio->count /* 取り出し */
	ld.w	%r4,[%r12]
	ext	0xa		; 	xld.ub	%r5, [%r12+0xa]		; %r5 = lfsr5 = audio->lfsr5 /* 取り出し */
	ld.ub	%r5,[%r12]
	ext	0xb		; 	xld.ub	%r6, [%r12+0xb]		; %r6 = lfsr4 = audio->lfsr4 /* 取り出し */
	ld.ub	%r6,[%r12]
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		; Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
	ext	0x1eb		; 	xld.w	%r14, 0x7ad0		; %r14 = clock = TIA_CLOCK / 114
	ld.w	%r14,0x10
	ext	0x5		; 	xld.w	%r15, 320			; %r15 = i = TIABUFLEN
	ld.w	%r15,0x0
tia_audio_mix3_DO:				; do {
	sub	%r4, %r14			;   count -= clock
	jruge	tia_audio_mix3_NO_ADVANCE	; 	xjruge	tia_audio_mix3_NO_ADVANCE	;   if(count < 0) { /*!NonCarry*/
tia_audio_mix3_ADVANCE_DO:			;     do {
	ld.w	%r9, %r5				; x = (LFSR5 ^ (LFSR5 >> 3)) & 1	; 	UPDATE_LFSR5	%r5			;       Update LFSR
	srl	%r9, 3
	xor	%r9, %r5
	and	%r9,0x1		; 	xand	%r9, %r9, 1
	srl	%r5,0x1		; 	xsrl	%r5, 1				; LFSR5 = (LFSR5 >> 1) | (x << (5 - 1))
	sll	%r9,0x4		; 	xsll	%r9, 0x4
	or	%r5, %r9
	ext	0x1		; 	xand	%r9, %r5, 1			;       if(lfsr5 & 1) {
	and	%r9,%r5
	jreq	tia_audio_mix3_ADVANCE_LOOP	; 	xjreq	tia_audio_mix3_ADVANCE_LOOP
	ld.w	%r9, %r6				; x = (lfsr4 ^ (lfsr4 >> 1)) & 1	; 	UPDATE_LFSR4	%r6			;         Update LFSR
	srl	%r9, 1
	xor	%r9, %r6
	and	%r9,0x1		; 	xand	%r9, %r9, 1
	srl	%r6,0x1		; 	xsrl	%r6, 1				; lfsr4 = (lfsr4 >> 1) | (x << (4 - 1))
	sll	%r9,0x3		; 	xsll	%r9, 0x3
	or	%r6, %r9
tia_audio_mix3_ADVANCE_LOOP:			;       }
	add	%r4, %r11			;     } while((count += period) < 0) /*NonCarry*/
	jruge	tia_audio_mix3_ADVANCE_DO	; 	xjruge	tia_audio_mix3_ADVANCE_DO
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		;     Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
tia_audio_mix3_NO_ADVANCE:			;   }
	ld.h	%r9, [%r13]			;   *wbuff++ += output
	add	%r9, %r7
	ld.h	[%r13]+, %r9
	;
	sub	%r15,0x1	; 	xsub	%r15, %r15, 1			; } while(--i)
	jrne	tia_audio_mix3_DO	; 	xjrne	tia_audio_mix3_DO
	;
	ext	0x4		; 	xld.w	%r4, [%r12+0x4]		; %r4 = audio->count = count /* 書き戻し */
	ld.w	%r4,[%r12]
	ext	0xa		; 	xld.b	%r5, [%r12+0xa]		; %r5 = audio->lfsr5 = lfsr5 /* 書き戻し */
	ld.b	%r5,[%r12]
	ext	0xb		; 	xld.b	%r6, [%r12+0xb]		; %r6 = audio->lfsr4 = lfsr4 /* 書き戻し */
	ld.b	%r6,[%r12]
tia_audio_mix3_EXIT:
	ret

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

;
;	30KHz/Freq pulse ----------------> Poly9 output ->
;
	.global	tia_audio_mix8
tia_audio_mix8:
	ld.ub	%r10,[%r12]	; 	xld.ub	%r10, [%r12+0x0]	; %r10 = volume = audio->volume
	cmp	%r10, 0				; !INTERLOCK!
	jreq	tia_audio_mix8_EXIT	; 	xjreq	tia_audio_mix8_EXIT		; if(!volume) goto EXIT
	;
	ext	0x1		; 	xld.ub	%r11, [%r12+0x1]	; %r11 = period = SPEAKER_FREQUENCY * audio->frequency
	ld.ub	%r11,[%r12]
	ext	0xfa		; 	xld.w	%r9, 16000		; *anti-interlock*
	ld.w	%r9,0x0
	mlt.h	%r11, %r9			; (16000×(1..32)なので、mlt.hで充分)
	ld.w	%r11, %alr
	;
	ext	0x4		; 	xld.w	%r4, [%r12+0x4]		; %r4 = count = audio->count /* 取り出し */
	ld.w	%r4,[%r12]
	ext	0x8		; 	xld.uh	%r6, [%r12+0x8]		; %r6 = lfsr9 = audio->lfsr9 /* 取り出し */	9-bit LFSRフィールドはHalfWordです。要注意!!
	ld.uh	%r6,[%r12]
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		; Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
	ext	0x1eb		; 	xld.w	%r14, 0x7ad0		; %r14 = clock = TIA_CLOCK / 114
	ld.w	%r14,0x10
	ext	0x5		; 	xld.w	%r15, 320			; %r15 = i = TIABUFLEN
	ld.w	%r15,0x0
tia_audio_mix8_DO:				; do {
	sub	%r4, %r14			;   count -= clock
	jruge	tia_audio_mix8_NO_ADVANCE	; 	xjruge	tia_audio_mix8_NO_ADVANCE	;   if(count < 0) { /*!NonCarry*/
tia_audio_mix8_ADVANCE_DO:			;     do {
	ld.w	%r9, %r6				; x = (LFSR9 ^ (LFSR9 >> 5)) & 1	; 	UPDATE_LFSR9	%r6			;         Update LFSR
	srl	%r9, 5
	xor	%r9, %r6
	and	%r9,0x1		; 	xand	%r9, %r9, 1
	srl	%r6,0x1		; 	xsrl	%r6, 1				; LFSR9 = (LFSR9 >> 1) | (x << (9 - 1))
	sll	%r9,0x8		; 	xsll	%r9, 0x8
	or	%r6, %r9
	add	%r4, %r11			;     } while((count += period) < 0) /*NonCarry*/
	jruge	tia_audio_mix8_ADVANCE_DO	; 	xjruge	tia_audio_mix8_ADVANCE_DO
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		;     Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
tia_audio_mix8_NO_ADVANCE:			;   }
	ld.h	%r9, [%r13]			;   *wbuff++ += output
	add	%r9, %r7
	ld.h	[%r13]+, %r9
	;
	sub	%r15,0x1	; 	xsub	%r15, %r15, 1			; } while(--i)
	jrne	tia_audio_mix8_DO	; 	xjrne	tia_audio_mix8_DO
	;
	ext	0x4		; 	xld.w	[%r12+0x4], %r4		; audio->count = count /* 書き戻し */
	ld.w	[%r12],%r4
	ext	0x8		; 	xld.h	[%r12+0x8], %r6		; audio->lfsr9 = lfsr9 /* 書き戻し */		9-bit LFSRフィールドはHalfWordです。要注意!!
	ld.h	[%r12],%r6
tia_audio_mix8_EXIT:
	ret

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

;
;	30KHz/Freq pulse ----------------> Poly5 output ->
;
	.global	tia_audio_mix9
tia_audio_mix9:
	ld.ub	%r10,[%r12]	; 	xld.ub	%r10, [%r12+0x0]	; %r10 = volume = audio->volume
	cmp	%r10, 0				; !INTERLOCK!
	jreq	tia_audio_mix9_EXIT	; 	xjreq	tia_audio_mix9_EXIT		; if(!volume) goto EXIT
	;
	ext	0x1		; 	xld.ub	%r11, [%r12+0x1]	; %r11 = period = SPEAKER_FREQUENCY * audio->frequency
	ld.ub	%r11,[%r12]
	ext	0xfa		; 	xld.w	%r9, 16000		; *anti-interlock*
	ld.w	%r9,0x0
	mlt.h	%r11, %r9			; (16000×(1..32)なので、mlt.hで充分)
	ld.w	%r11, %alr
	;
	ext	0x4		; 	xld.w	%r4, [%r12+0x4]		; %r4 = count = audio->count /* 取り出し */
	ld.w	%r4,[%r12]
	ext	0xa		; 	xld.ub	%r6, [%r12+0xa]		; %r6 = lfsr5 = audio->lfsr5 /* 取り出し */
	ld.ub	%r6,[%r12]
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		; Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
	ext	0x1eb		; 	xld.w	%r14, 0x7ad0		; %r14 = clock = TIA_CLOCK / 114
	ld.w	%r14,0x10
	ext	0x5		; 	xld.w	%r15, 320			; %r15 = i = TIABUFLEN
	ld.w	%r15,0x0
tia_audio_mix9_DO:				; do {
	sub	%r4, %r14			;   count -= clock
	jruge	tia_audio_mix9_NO_ADVANCE	; 	xjruge	tia_audio_mix9_NO_ADVANCE	;   if(count < 0) { /*!NonCarry*/
tia_audio_mix9_ADVANCE_DO:			;     do {
	ld.w	%r9, %r6				; x = (LFSR5 ^ (LFSR5 >> 3)) & 1	; 	UPDATE_LFSR5	%r6			;         Update LFSR
	srl	%r9, 3
	xor	%r9, %r6
	and	%r9,0x1		; 	xand	%r9, %r9, 1
	srl	%r6,0x1		; 	xsrl	%r6, 1				; LFSR5 = (LFSR5 >> 1) | (x << (5 - 1))
	sll	%r9,0x4		; 	xsll	%r9, 0x4
	or	%r6, %r9
	add	%r4, %r11			;     } while((count += period) < 0) /*NonCarry*/
	jruge	tia_audio_mix9_ADVANCE_DO	; 	xjruge	tia_audio_mix9_ADVANCE_DO
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		;     Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
tia_audio_mix9_NO_ADVANCE:			;   }
	ld.h	%r9, [%r13]			;   *wbuff++ += output
	add	%r9, %r7
	ld.h	[%r13]+, %r9
	;
	sub	%r15,0x1	; 	xsub	%r15, %r15, 1			; } while(--i)
	jrne	tia_audio_mix9_DO	; 	xjrne	tia_audio_mix9_DO
	;
	ext	0x4		; 	xld.w	[%r12+0x4], %r4		; audio->count = count /* 書き戻し */
	ld.w	[%r12],%r4
	ext	0xa		; 	xld.b	[%r12+0xa], %r6		; audio->lfsr5 = lfsr5 /* 書き戻し */
	ld.b	[%r12],%r6
tia_audio_mix9_EXIT:
	ret

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

;
;	30KHz/Freq pulse -> Div31 pulse -> Poly5 output ->
;
	.global	tia_audio_mixA
tia_audio_mixA:
	ld.ub	%r10,[%r12]	; 	xld.ub	%r10, [%r12+0x0]	; %r10 = volume = audio->volume
	cmp	%r10, 0				; !INTERLOCK!
	jreq	tia_audio_mixA_EXIT	; 	xjreq	tia_audio_mixA_EXIT		; if(!volume) goto EXIT
	;
	ext	0x1		; 	xld.ub	%r11, [%r12+0x1]	; %r11 = period = SPEAKER_FREQUENCY * audio->frequency
	ld.ub	%r11,[%r12]
	ext	0xfa		; 	xld.w	%r9, 16000		; *anti-interlock*
	ld.w	%r9,0x0
	mlt.h	%r11, %r9			; (16000×(1..32)なので、mlt.hで充分)
	ld.w	%r11, %alr
	;
	ext	0x4		; 	xld.w	%r4, [%r12+0x4]		; %r4 = count = audio->count /* 取り出し */
	ld.w	%r4,[%r12]
	ext	0x3		; 	xld.ub	%r5, [%r12+0x3]		; %r5 = div31 = audio->div31 /* 取り出し */
	ld.ub	%r5,[%r12]
	ext	0xa		; 	xld.ub	%r6, [%r12+0xa]		; %r6 = lfsr5 = audio->lfsr5 /* 取り出し */
	ld.ub	%r6,[%r12]
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		; Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
	ext	0x1eb		; 	xld.w	%r14, 0x7ad0		; %r14 = clock = TIA_CLOCK / 114
	ld.w	%r14,0x10
	ext	0x5		; 	xld.w	%r15, 320			; %r15 = i = TIABUFLEN
	ld.w	%r15,0x0
tia_audio_mixA_DO:				; do {
	sub	%r4, %r14			;   count -= clock
	jruge	tia_audio_mixA_NO_ADVANCE	; 	xjruge	tia_audio_mixA_NO_ADVANCE	;   if(count < 0) { /*!NonCarry*/
tia_audio_mixA_ADVANCE_DO:			;     do {
	sub	%r5,0x1		; 	xsub	%r5, %r5, 1			;       if(--div31 < 0) div31 += 31
	jruge	2
	add	%r5, 31				;       (skip?)
	jreq	2
	cmp	%r5, 13				;       (skip?)
	jrne	tia_audio_mixA_ADVANCE_LOOP	; 	xjrne	tia_audio_mixA_ADVANCE_LOOP	;       if(div31 == 0 || div31 == 13) {
	ld.w	%r9, %r6				; x = (LFSR5 ^ (LFSR5 >> 3)) & 1	; 	UPDATE_LFSR5	%r6			;         Update LFSR
	srl	%r9, 3
	xor	%r9, %r6
	and	%r9,0x1		; 	xand	%r9, %r9, 1
	srl	%r6,0x1		; 	xsrl	%r6, 1				; LFSR5 = (LFSR5 >> 1) | (x << (5 - 1))
	sll	%r9,0x4		; 	xsll	%r9, 0x4
	or	%r6, %r9
tia_audio_mixA_ADVANCE_LOOP:			;       }
	add	%r4, %r11			;     } while((count += period) < 0) /*NonCarry*/
	jruge	tia_audio_mixA_ADVANCE_DO	; 	xjruge	tia_audio_mixA_ADVANCE_DO
	;
	ext	0x1		; 	xand	%r9, %r6, 1			; output = (lfsr/polar & 1) ? volume : -volume	; 	UPDATE_OUTPUT	%r6, %r7, %r10		;     Update output
	and	%r9,%r6
	jrne.d	4
	ld.w	%r7, %r10				; *delay*
	not	%r7, %r7				; (skip?)
	add	%r7, 1				; (skip?)
	;
tia_audio_mixA_NO_ADVANCE:			;   }
	ld.h	%r9, [%r13]			;   *wbuff++ += output
	add	%r9, %r7
	ld.h	[%r13]+, %r9
	;
	sub	%r15,0x1	; 	xsub	%r15, %r15, 1			; } while(--i)
	jrne	tia_audio_mixA_DO	; 	xjrne	tia_audio_mixA_DO
	;
	ext	0x4		; 	xld.w	[%r12+0x4], %r4		; audio->count = count /* 書き戻し */
	ld.w	[%r12],%r4
	ext	0x3		; 	xld.b	[%r12+0x3], %r5		; audio->div31 = div31 /* 書き戻し */
	ld.b	[%r12],%r5
	ext	0xa		; 	xld.b	[%r12+0xa], %r6		; audio->lfsr5 = lfsr5 /* 書き戻し */
	ld.b	[%r12],%r6
tia_audio_mixA_EXIT:
	ret

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

;#endif /*TIA_ASM*/
