;	
;	framsp2a.s
;
;	P/ECE SPC Driver V2
;
;	CLiP - Common Library for P/ECE
;	Copyright (C) 2001-2004 Naoyuki Sawa
;
;	* Mon Oct 11 12:53:00 JST 2004 Naoyuki Sawa
;	- 作成開始。
;
;#include "clipsp2a.h"
;/	
;/	clipsp2a.h
;/
;/	P/ECE S-SMP (SPC700) Emulator
;/
;/	CLiP - Common Library for P/ECE
;/	Copyright (C) 2001-2004 Naoyuki Sawa
;/
;/	* Mon Oct 11 04:21:00 JST 2004 Naoyuki Sawa
;/	- 作成開始。
;/

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

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

;#include "clipsp2b.h"
;	
;	clipsp2b.h
;
;	P/ECE SPC Driver V2
;
;	CLiP - Common Library for P/ECE
;	Copyright (C) 2001-2004 Naoyuki Sawa
;
;	* Thu Oct 14 19:00:00 JST 2004 Naoyuki Sawa
;	- 作成開始。
;

;★★★★★★★★★★★★★★★★★★★★★★★★★★
;★ clipsp2a.sとframsp2a.sからインクルードします。 ★
;★ Ｃ言語ソースからインクルードしてはいけません。 ★
;★★★★★★★★★★★★★★★★★★★★★★★★★★

;****************************************************************************
;	SPC2CPU
;****************************************************************************

;
;	SPC2CPU構造体
;
;#define PSW_P		 0
;#define PSW_NZ		 2
;#define PSW_C		 3
;#define PSW_CNZ		 2
;#define PSW_V		 4
;#define X		 5
;#define A		 6
;#define Y		 7
;#define YA		 6
;#define SP		 8
;#define PC		12
;#define SPC2CPU_SIZE	16

;
;	関数呼び出しの簡略表記
;
;#macro READ
;	xcall spc2cpu_READ
;#endm
;#macro WRITE
;	xcall spc2cpu_WRITE
;#endm
;#macro READW
;	xcall spc2cpu_READW
;#endm
;#macro WRITEW
;	xcall spc2cpu_WRITEW
;#endm
;#macro ADC
;	xcall spc2cpu_ADC
;#endm
;#macro SBC
;	xcall spc2cpu_SBC
;#endm
;#macro ADDW
;	xcall spc2cpu_ADDW
;#endm
;#macro SUBW
;	xcall spc2cpu_SUBW
;#endm
;#macro BEQ
;	xcall spc2cpu_BEQ
;#endm
;#macro BNE
;	xcall spc2cpu_BNE
;#endm
;#macro DIV
;	xcall spc2cpu_DIV
;#endm
;#macro PACK_PSW
;	xcall spc2cpu_PACK_PSW
;#endm
;#macro UNPACK_PSW
;	xcall spc2cpu_UNPACK_PSW
;#endm
;#macro DIE $1
;	xld.w %r12, $1
;	xcall spc2cpu_DIE
;#endm

;
;	アドレッシングモード
;
;	*** RELATIVE以外に関する説明 ***
;
;	[out]
;		%r12		ひとつめのアドレス。
;		%r13		ふたつめのアドレス。(あれば)
;	[mod]
;		%r12-15		%r12-15のうち、戻り値として使用しないレジスタは、
;				アドレッシングモードマクロの内部計算で破壊されると考えてください。
;				- %r12-15のうち、現在の実装で破壊されていないレジスタも、
;				  今後の変更によって、破壊されるようになる可能性があります。
;				- 実際には、アドレッシングモードマクロはインストラクション処理の最初に
;				  呼ばれることがほとんどなので、レジスタ破壊を気にする必要はないはずです。
;
;	[note]
;		* ふたつのアドレスを返すアドレッシングモードの場合、
;		  ひとつめのアドレスが転送元、ふたつめのアドレスが転送先となることに注意してください。
;		  これは、インストラクション表記の引数順序とは異なります。
;
;		  <例> "dp(d),dp(s)"の場合、%r12=dp(s),%r13=dp(d)
;
;		  このようにした理由は以下のとおりです。
;
;		  - 機械語の後続バイト並びが、転送元,転送先の順です。
;		    前出の例ですと、命令コードの後にはdp(s)のアドレス、その後にdp(d)のアドレスがあります。
;		    感覚的に、機械語の並び順と同じ方がわかりやすいと判断しました。
;		  - spc2cpu_READ,spc2cpu_WRITEは、%r12にアドレスを入れて呼び出します。
;		    アドレッシングモード計算後、最初に転送元アドレスからのREADを行うことが多いので、
;		    %r12に転送元アドレスが入っていた方が使いやすいです。
;
;	
;	*** RELATIVEだけに関する説明 ***
;
;	[out]
;		%r1		更新されたPC。
;	[mod]
;		%r9		RELATIVEだけはインストラクション処理の途中で呼ばれることがあるので、
;				%r12-15や、その他の一般レジスタもなるべく破壊したくありません。
;				そこで、ext33のワークレジスタ%r9を使いました。
;				通常のプログラムは%r9を使わないので、RELATIVEは破壊レジスタ無しと考えて構いません。
;
;* 1. #inm */
;#macro INMEDIATE_DATA
;	ld.ub %r12, [%r1]+		; inm = *PC++
;#endm
;* 2. dp */
;#macro DIRECT_PAGE
;	xld.uh %r15, [%r0+PSW_P]	; mem = PSW_P | *PC++
;	ld.ub %r12, [%r1]+
;	or %r12, %r15
;#endm
;* 3. dp+X */
;#macro X_INDEXED_DIRECT_PAGE
;	xld.uh %r15, [%r0+PSW_P]	; mem = PSW_P | (unsigned char)(*PC++ + X)
;	ld.ub %r12, [%r1]+
;	xld.ub %r13, [%r0+X]
;	add %r12, %r13
;	ld.ub %r12, %r12
;	or %r12, %r15
;#endm
;* 4. dp+Y */
;#macro Y_INDEXED_DIRECT_PAGE
;	xld.uh %r15, [%r0+PSW_P]	; mem = PSW_P | (unsigned char)(*PC++ + Y)
;	ld.ub %r12, [%r1]+
;	xld.ub %r13, [%r0+Y]
;	add %r12, %r13
;	ld.ub %r12, %r12
;	or %r12, %r15
;#endm
;* 5. (X) */
;#macro INDIRECT
;	xld.uh %r15, [%r0+PSW_P]	; mem = PSW_P | X
;	xld.ub %r12, [%r0+X]
;	or %r12, %r15
;#endm
;* 6. (X)+ */
;#macro INDIRECT_AUTO_INCREMENT
;	xld.uh %r15, [%r0+PSW_P]	; mem = PSW_P | X++
;	xld.ub %r12, [%r0+X]
;	xadd %r13, %r12, 1
;	xld.b [%r0+X], %r13
;	or %r12, %r15
;#endm
;* 7. (X),(Y) */
;#macro INDIRECT_PAGE_TO_IP
;	xld.uh %r15, [%r0+PSW_P]
;	xld.ub %r12, [%r0+Y]		; src = PSW_P | Y
;	xld.ub %r13, [%r0+X]		; dst = PSW_P | X
;	or %r12, %r15
;	or %r13, %r15
;#endm
;* 8. dp(d),dp(s) */
;#macro DIRECT_PAGE_TO_DP
;	xld.uh %r15, [%r0+PSW_P]
;	ld.ub %r12, [%r1]+		; src = PSW_P | *PC++
;	ld.ub %r13, [%r1]+		; dst = PSW_P | *PC++
;	or %r12, %r15
;	or %r13, %r15
;#endm
;* 9. dp,#inm */
;#macro INMEDIATE_DATA_TO_DP
;	xld.uh %r15, [%r0+PSW_P]
;	ld.ub %r12, [%r1]+		; inm = *PC++
;	ld.ub %r13, [%r1]+		; mem = PSW_P | *PC++
;	or %r13, %r15
;#endm
;* 10. labs */
;#macro ABSOLUTE
;	ld.ub %r12, [%r1]+		; mem  = *PC++
;	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
;	xsll %r13, 8
;	or %r12, %r13
;#endm
;* 11. labs+X */
;#macro X_INDEXED_ABSOLUTE
;	ld.ub %r12, [%r1]+		; mem  = *PC++
;	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
;	xld.ub %r14, [%r0+X]		; mem  = (unsigned short)(mem + X)
;	xsll %r13, 8
;	or %r12, %r13
;	add %r12, %r14
;	ld.uh %r12, %r12
;#endm
;* 12. labs+Y */
;#macro Y_INDEXED_ABSOLUTE
;	ld.ub %r12, [%r1]+		; mem  = *PC++
;	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
;	xld.ub %r14, [%r0+Y]		; mem  = (unsigned short)(mem + Y)
;	xsll %r13, 8
;	or %r12, %r13
;	add %r12, %r14
;	ld.uh %r12, %r12
;#endm
;* 13. (dp+X) */
;#macro X_INDEXED_INDIRECT
;	xld.uh %r15, [%r0+PSW_P]	; mem = PSW_P | (unsigned char)(*PC++ + X)
;	ld.ub %r13, [%r1]+
;	xld.ub %r14, [%r0+X]
;	add %r13, %r14
;	ld.ub %r13, %r13
;	or %r13, %r15
;	ext spc2ram@ah			; mem = spc2ram[mem] | spc2ram[mem + 1] << 8
;	ext spc2ram@al
;	add %r13, %r13
;	ld.ub %r12, [%r13]+
;	ld.ub %r13, [%r13]
;	xsll %r13, 8
;	or %r12, %r13
;#endm
;* 14. (dp)+Y */
;#macro INDIRECT_Y_INDEXED_INDIRECT
;	xld.uh %r15, [%r0+PSW_P]	; mem = PSW_P | *PC++
;	ld.ub %r13, [%r1]+
;	or %r13, %r15
;	ext spc2ram@ah			; mem = spc2ram[mem] | spc2ram[mem + 1] << 8
;	ext spc2ram@al			; mem = (unsigned short)(mem + Y)
;	add %r13, %r13
;	ld.ub %r12, [%r13]+
;	ld.ub %r13, [%r13]
;	xld.ub %r14, [%r0+Y]
;	xsll %r13, 8
;	or %r12, %r13
;	add %r12, %r14
;	ld.uh %r12, %r12
;#endm
;* 15. rel */
;#macro RELATIVE
	; 他のアドレッシングモードがインストラクション処理の先頭だけで呼ばれるのに対し、
	; RELATIVEだけはインストラクション処理の途中で呼ばれることがあるので、
	; %r12-15や、その他の一般レジスタもなるべく破壊したくありません。
	; そこで、ext33のワークレジスタ%r9を使います。
	; RELATIVEの実装に、ext33の拡張命令(xldとか)を使わないよう、気をつけてください。
;	ld.b %r9, [%r1]+		; tmp = (char)*PC++
;	ext spc2ram@ah			; PC = &spc2ram[(unsigned short)(PC - spc2ram + tmp)]
;	ext spc2ram@al
;	sub %r1, %r1
;	add %r1, %r9
;	ld.uh %r1, %r1
;	ext spc2ram@ah
;	ext spc2ram@al
;	add %r1, %r1
;#endm
;* 16. (labs+X) */
;#macro X_INDEXED_ABSOLUTE_INDIRECT
;	ld.ub %r13, [%r1]+		; mem  = *PC++
;	ld.ub %r14, [%r1]+		; mem |= *PC++ << 8
;	xld.ub %r15, [%r0+X]		; mem  = (unsigned short)(mem + X)
;	xsll %r14, 8
;	or %r13, %r14
;	add %r13, %r15
;	ld.uh %r13, %r13
;	ext spc2ram@ah			; mem  = spc2ram[mem] | spc2ram[mem + 1] << 8
;	ext spc2ram@al
;	add %r13, %r13
;	ld.ub %r12, [%r13]+
;	ld.ub %r13, [%r13]
;	xsll %r13, 8
;	or %r12, %r13
;#endm
;* 17. mem.bit */
;#macro ABSOLUTE_BOOLEAN_BIT
;	ld.ub %r13, [%r1]+		; bit   = *PC++
;	ld.ub %r14, [%r1]+		; bit  |= *PC++ << 8
;	xsll %r14, 8
;	or %r13, %r14
;	xand %r12, %r13, 0x1fff		; mem   = bit & 0x1fff
;	xsrl %r13, 13			; bit >>= 13
;#endm

;****************************************************************************
;	SPC2DSP
;****************************************************************************

;
;	SPC2VCE構造体
;
;#define STATE		 0
;#define VOL		 4
;#define P		 8
;#define AR		12
;#define DR		16
;#define SR		20
;#define SL		24
;#define GAIN		28
;#define ENVX		32
;#define LSA		36
;#define BRR_ADDR	40
;#define LAST_LOOP	44
;#define PROGRESS	48
;#define SAMPLE		52

;
;	SPC2DSP構造体
;
;#define MVOL		  0
;#define VCE		  4
;#define REG		676

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

;#ifdef SPC2_ASM

; * 頻繁にアクセスされるSPC2CPU構造体を高速RAMに配置して、高速化を図ります。
;   SPC2CPU構造体は書き換え対象なので、本当は.codeセクションに配置するのは良くないのですが、
;   clip.mkにて.codeセクションだけを高速RAMへ転送するように設定してあるので、仕方ないです。
;   P/ECEは.code,.data,.bss全部RAM上に展開して実行するので、動作上は問題ありません。
; * メモリ領域を.codeセクションに配置するために、.commではなく.spaceを使っています。
;   .commを使うと強制的に.bssセクションに配置されてしまうので、ダメです。
	.code
	.align 2
	.global spc2cpu
spc2cpu:
	.space 16

	.code
	.align 1

;****************************************************************************
;	SPC2CPU
;****************************************************************************

;
; 重要!!
; %r3=countであることを、spc2cpu_runから呼ばれる他のルーチンが利用しています。
; 無駄ループを検出すると%r3の値を変更し、残りタイムスライスを放棄します。
; %r3=countのレジスタ割り当てを変更しないでください。
; 詳しくは、spc2cpu_READとspc2drv_read_asmの実装を参照してください。
;
	.global spc2cpu_run
spc2cpu_run:
	pushn %r3

	ext	spc2cpu+0x0@h	; 	xld.w %r0, spc2cpu		; cpu = &spc2cpu
	ext	spc2cpu+0x0@m
	ld.w	%r0,spc2cpu+0x0@l
	ext	0xc		; 	xld.w %r1, [%r0+0xc]		; PC = cpu->pc
	ld.w	%r1,[%r0]
	ext	spc2cpu_TABLE+0x0@h	; 	xld.w %r2, spc2cpu_TABLE	; spc2cpu_TABLE
	ext	spc2cpu_TABLE+0x0@m
	ld.w	%r2,spc2cpu_TABLE+0x0@l
	ld.w %r3, %r12			; count ★このレジスタ割り当て変更不可!!★
	; %r0 = cpu
	; %r1 = PC
	; %r2 = spc2cpu_TABLE
	; %r3 = count ★このレジスタ割り当て変更不可!!★

spc2cpu_run_L10:			; do {

;;{{SPC2_TRACE
;;	pushn %r15
;;	xld.w %r0, [spc2cpu+PC]
;;	xld.w [spc2cpu+PC], %r1
;;	xcall spc2cpu_dump
;;	xld.w [spc2cpu+PC], %r0
;;	popn %r15
;;}}SPC2_TRACE

	ld.ub %r4, [%r1]+		; switch(*PC++)
	sll	%r4,0x2		; 	xsll %r4, 2
	add %r4, %r2
	ld.w %r4, [%r4]
	call %r4

	sub	%r3,0x1		; 	xsub %r3, %r3, 1		; } while(--count > 0)
	jrgt	spc2cpu_run_L10	; 	xjrgt spc2cpu_run_L10

	ext	0xc		; 	xld.w [%r0+0xc], %r1		; cpu->pc = PC
	ld.w	[%r0],%r1

	popn %r3
	ret

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

;
; 符号無し8bit値を読み出します。
; [in]
;	%r12		読み出すアドレス。
; [out]
;	%r10		読み出したデータ。
; [mod]
;	%r0-3		保存
;	%r4-7		破壊
;	%r8-9		予約
;	%r10		戻り値
;	%r11		破壊
;	%r12-15		保存
;
	.global spc2cpu_READ
spc2cpu_READ:
	ext	0xf0		; 	xsub %r10, %r12, 0xf0		; if((unsigned)(addr - 0xf0) > 0xf) {
	sub	%r10,%r12
	cmp	%r10,0xf	; 	xcmp %r10, 0xf
	jrule	spc2cpu_READ_L10	; 	xjrule spc2cpu_READ_L10
	ext spc2ram@ah			;   return spc2ram[addr]
	ext spc2ram@al
	ld.ub %r10, [%r12]
	ret
spc2cpu_READ_L10:			; } else {
	sub	%sp,0x4		; 	xsub %sp, %sp, 16
	ld.w	[%sp+0x0],%r12	; 	xld.w [%sp+ 0x0], %r12
	ld.w	[%sp+0x1],%r13	; 	xld.w [%sp+ 0x4], %r13
	ld.w	[%sp+0x2],%r14	; 	xld.w [%sp+ 0x8], %r14
	ld.w	[%sp+0x3],%r15	; 	xld.w [%sp+0xc], %r15
	;;xcall spc2drv_read		;   return spc2drv_read(addr)
	;;↓高速版。
	;;↓無駄ループを検出すると、%r3(spc2cpu_runの命令実行回数)をゼロにして、残りタイムスライスを放棄します。
	;;↓clipsp2.cのspc2drv_read_asmを参照してください。
	ext	spc2drv_read_asm@rm	; 	xcall spc2drv_read_asm		;   return spc2drv_read_asm(addr)
	call	spc2drv_read_asm@rl
	ld.w	%r12,[%sp+0x0]	; 	xld.w %r12, [%sp+ 0x0]
	ld.w	%r13,[%sp+0x1]	; 	xld.w %r13, [%sp+ 0x4]
	ld.w	%r14,[%sp+0x2]	; 	xld.w %r14, [%sp+ 0x8]
	ld.w	%r15,[%sp+0x3]	; 	xld.w %r15, [%sp+0xc]
	add	%sp,0x4		; 	xadd %sp, %sp, 16
	ret				; }

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

;
; 8bit値を書き込みます。
; [in]
;	%r12		書き込むアドレス。
;	%r13		書き込むデータ。([31:8]は不定でも構いません)
; [mod]
;	%r0-3		保存
;	%r4-7		破壊
;	%r8-9		予約
;	%r10-11		破壊
;	%r12-15		保存
;
	.global spc2cpu_WRITE
spc2cpu_WRITE:
;;{{SPC2_TRACE
;;	pushn %r15
;;	xcall spc2cpu_write_trace
;;	popn %r15
;;}}SPC2_TRACE
	ext	0xf0		; 	xsub %r10, %r12, 0xf0		; if((unsigned)(addr - 0xf0) > 0xf) {
	sub	%r10,%r12
	cmp	%r10,0xf	; 	xcmp %r10, 0xf
	jrule	spc2cpu_WRITE_L10	; 	xjrule spc2cpu_WRITE_L10
	ext spc2ram@ah			;   spc2ram[addr] = data
	ext spc2ram@al
	ld.b [%r12], %r13
	ret
spc2cpu_WRITE_L10:			; } else {
	sub	%sp,0x4		; 	xsub %sp, %sp, 16
	ld.w	[%sp+0x0],%r12	; 	xld.w [%sp+ 0x0], %r12
	ld.w	[%sp+0x1],%r13	; 	xld.w [%sp+ 0x4], %r13
	ld.w	[%sp+0x2],%r14	; 	xld.w [%sp+ 0x8], %r14
	ld.w	[%sp+0x3],%r15	; 	xld.w [%sp+0xc], %r15
	ld.ub %r13, %r13		;   spc2drv_writeへ渡すdata[32:8]はゼロ必須!
	ext	spc2drv_write@rm	; 	xcall spc2drv_write		;   spc2drv_write(addr, (unsigned char)data)
	call	spc2drv_write@rl
	ld.w	%r12,[%sp+0x0]	; 	xld.w %r12, [%sp+ 0x0]
	ld.w	%r13,[%sp+0x1]	; 	xld.w %r13, [%sp+ 0x4]
	ld.w	%r14,[%sp+0x2]	; 	xld.w %r14, [%sp+ 0x8]
	ld.w	%r15,[%sp+0x3]	; 	xld.w %r15, [%sp+0xc]
	add	%sp,0x4		; 	xadd %sp, %sp, 16
	ret				; }

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

;
; 符号無し16bit値を読み出します。
; [in]
;	%r12		読み出すアドレス。
; [out]
;	%r10		読み出したデータ。
; [mod]
;	%r0-3		保存
;	%r4-7		破壊
;	%r8-9		予約
;	%r10		戻り値
;	%r11		破壊
;	%r12-15		保存
;
	.global spc2cpu_READW
spc2cpu_READW:
	sub	%sp,0x1		; 	xsub %sp, %sp, 4

	call	spc2cpu_READ	; 	xcall spc2cpu_READ
	ld.w	[%sp+0x0],%r10	; 	xld.w [%sp+0x0], %r10

	add	%r12,0x1	; 	xadd %r12, %r12, 1
	call	spc2cpu_READ	; 	xcall spc2cpu_READ
	sub	%r12,0x1	; 	xsub %r12, %r12, 1

	sll	%r10,0x8	; 	xsll %r10, 8
	ld.w	%r11,[%sp+0x0]	; 	xld.w %r11, [%sp+0x0]
	or %r10, %r11

	add	%sp,0x1		; 	xadd %sp, %sp, 4
	ret

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

;
; 16bit値を書き込みます。
; [in]
;	%r12		書き込むアドレス。
;	%r13		書き込むデータ。([31:16]は不定でも構いません)
; [mod]
;	%r0-3		保存
;	%r4-7		破壊
;	%r8-9		予約
;	%r10-11		破壊
;	%r12-15		保存
;
	.global spc2cpu_WRITEW
spc2cpu_WRITEW:
	call	spc2cpu_WRITE	; 	xcall spc2cpu_WRITE

	add	%r12,0x1	; 	xadd %r12, %r12, 1
	rr	%r13,0x8	; 	xrr %r13, 8
	call	spc2cpu_WRITE	; 	xcall spc2cpu_WRITE
	sub	%r12,0x1	; 	xsub %r12, %r12, 1
	rl	%r13,0x8	; 	xrl %r13, 8

	ret

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

;
; キャリー込み8bit加算を行います。
; [in]
;	%r0	SPC2CPU構造体。
;	%r14	足される数。
;	%r15	足す数。
; [out]
;	%r13	結果。([31:8]は不定です)
; [mod]
;	%r0-7	保存
;	%r8-9	予約
;	%r10-11	破壊 (現在の実装では保存ですが、今後のために破壊と考えておく)
;	%r12	保存
;	%r13	戻り値
;	%r14-15	破壊
;
	.global spc2cpu_ADC
spc2cpu_ADC:
	ext	0x3		; 	xld.ub %r13, [%r0+0x3]	; tmp = a + b + ((PSW_C & 1) ? 1 : 0)
	ld.ub	%r13,[%r0]
	and	%r13,0x1	; 	xand %r13, %r13, 1
	add %r13, %r14
	add %r13, %r15

	xor %r15, %r14			; PSW_V = ~(a ^ b) & (a ^ tmp)
	not %r15, %r15
	xor %r14, %r13
	and %r14, %r15
	ext	0x4		; 	xld.b [%r0+0x4], %r14
	ld.b	[%r0],%r14

	ext	0x2		; 	xld.h [%r0+0x2], %r13	; PSW_CNZ = tmp
	ld.h	[%r0],%r13

	ret

;
; キャリー込み8bit減算を行います。
; [in]
;	%r0	SPC2CPU構造体。
;	%r14	引かれる数。
;	%r15	引く数。
; [out]
;	%r13	結果。([31:8]は不定です)
; [mod]
;	%r0-7	保存
;	%r8-9	予約
;	%r10-11	破壊 (現在の実装では保存ですが、今後のために破壊と考えておく)
;	%r12	保存
;	%r13	戻り値
;	%r14-15	破壊
;
	.global spc2cpu_SBC
spc2cpu_SBC:
	ext	0x3		; 	xld.ub %r13, [%r0+0x3]	; tmp = a - b + ((PSW_C & 1) ? 0 : -1)
	ld.ub	%r13,[%r0]
	and	%r13,0x1	; 	xand %r13, %r13, 1
	sub	%r13,0x1	; 	xsub %r13, %r13, 1
	add %r13, %r14
	sub %r13, %r15

	xor %r15, %r14			; PSW_V = (a ^ b) & (a ^ tmp)
	xor %r14, %r13
	and %r14, %r15
	ext	0x4		; 	xld.b [%r0+0x4], %r14
	ld.b	[%r0],%r14

	ext	0x4		; 	xxor %r13, %r13, 0x100		; PSW_CNZ = tmp ^ 0x100
	xor	%r13,0x0
	ext	0x2		; 	xld.h [%r0+0x2], %r13
	ld.h	[%r0],%r13

	ret

;
; キャリー無し16bit加算を行います。
; [in]
;	%r0	SPC2CPU構造体。
;	%r14	足される数。
;	%r15	足す数。
; [out]
;	%r13	結果。([31:16]は不定です)
; [mod]
;	%r0-7	保存
;	%r8-9	予約
;	%r10-11	破壊 (現在の実装では保存ですが、今後のために破壊と考えておく)
;	%r12	保存
;	%r13	戻り値
;	%r14-15	破壊
;
	.global spc2cpu_ADDW
spc2cpu_ADDW:
	ld.w %r13, %r14			; tmp = a + b
	add %r13, %r15

	xor %r15, %r14			; PSW_V = (~(a ^ b) & (a ^ tmp)) >> 8
	not %r15, %r15
	xor %r14, %r13
	and %r14, %r15
	srl	%r14,0x8	; 	xsrl %r14, 8
	ext	0x4		; 	xld.b [%r0+0x4], %r14
	ld.b	[%r0],%r14

	ld.w %r14, %r13			; PSW_CNZ = (tmp >> 8) | ((unsigned short)tmp != 0)
	ext	0x7		; 	xand %r15, %r13, 0xffff
	ext	0x1fff
	and	%r15,%r13
	jreq.d 3
	srl %r14, 8			; *delay*
	or %r14, 1
	ext	0x2		; 	xld.h [%r0+0x2], %r14
	ld.h	[%r0],%r14

	ret

;
; キャリー無し16bit減算を行います。
; [in]
;	%r0	SPC2CPU構造体。
;	%r14	引かれる数。
;	%r15	引く数。
; [out]
;	%r13	結果。([31:16]は不定です)
; [mod]
;	%r0-7	保存
;	%r8-9	予約
;	%r10-11	破壊 (現在の実装では保存ですが、今後のために破壊と考えておく)
;	%r12	保存
;	%r13	戻り値
;	%r14-15	破壊
;
	.global spc2cpu_SUBW
spc2cpu_SUBW:
	ld.w %r13, %r14			; tmp = a - b
	sub %r13, %r15

	xor %r15, %r14			; PSW_V = ((a ^ b) & (a ^ tmp)) >> 8
	xor %r14, %r13
	and %r14, %r15
	srl	%r14,0x8	; 	xsrl %r14, 8
	ext	0x4		; 	xld.b [%r0+0x4], %r14
	ld.b	[%r0],%r14

	ld.w %r14, %r13			; PSW_CNZ = ((tmp >> 8) | ((unsigned short)tmp != 0)) ^ 0x100
	ext	0x7		; 	xand %r15, %r13, 0xffff
	ext	0x1fff
	and	%r15,%r13
	jreq.d 3
	srl %r14, 8			; *delay*
	or %r14, 1
	ext	0x4		; 	xxor %r14, %r14, 0x100
	xor	%r14,0x0
	ext	0x2		; 	xld.h [%r0+0x2], %r14
	ld.h	[%r0],%r14

	ret

;
; ゼロフラグが1ならば分岐します。
; [in]
;	%r0		SPC2CPU構造体。
;	%r1		PC。
;	%psr(Z)		1ならば分岐します。
;			0ならば分岐しません。
; [out]
;	%r1		更新されたPC。
; [mod]
;	%r0-7	保存
;	%r8-9	予約
;	%r10-11	破壊 (現在の実装では保存ですが、今後のために破壊と考えておく)
;	%r12-15	保存
;
	.global spc2cpu_BEQ
spc2cpu_BEQ:
	jreq	spc2cpu_BEQ_L10	; 	xjreq spc2cpu_BEQ_L10		; if(!EQ) {
	ret.d				;   PC++
	add %r1, 1			;   *delay*
spc2cpu_BEQ_L10:			; } else {
	; 他のアドレッシングモードがインストラクション処理の先頭だけで呼ばれるのに対し、	; 	RELATIVE			;   RELATIVE
	; RELATIVEだけはインストラクション処理の途中で呼ばれることがあるので、
	; %r12-15や、その他の一般レジスタもなるべく破壊したくありません。
	; そこで、ext33のワークレジスタ%r9を使います。
	; RELATIVEの実装に、ext33の拡張命令(xldとか)を使わないよう、気をつけてください。
	ld.b %r9, [%r1]+		; tmp = (char)*PC++
	ext spc2ram@ah			; PC = &spc2ram[(unsigned short)(PC - spc2ram + tmp)]
	ext spc2ram@al
	sub %r1, %r1
	add %r1, %r9
	ld.uh %r1, %r1
	ext spc2ram@ah
	ext spc2ram@al
	add %r1, %r1
	ret				; }

;
; ゼロフラグが0ならば分岐します。
; [in]
;	%r0		SPC2CPU構造体。
;	%r1		PC。
;	%psr(Z)		0ならば分岐します。
;			1ならば分岐しません。
; [out]
;	%r1		更新されたPC。
; [mod]
;	%r0-7	保存
;	%r8-9	予約
;	%r10-11	破壊 (現在の実装では保存ですが、今後のために破壊と考えておく)
;	%r12-15	保存
;
	.global spc2cpu_BNE
spc2cpu_BNE:
	jrne	spc2cpu_BNE_L10	; 	xjrne spc2cpu_BNE_L10		; if(!NE) {
	ret.d				;   PC++
	add %r1, 1			;   *delay*
spc2cpu_BNE_L10:			; } else {
	; 他のアドレッシングモードがインストラクション処理の先頭だけで呼ばれるのに対し、	; 	RELATIVE			;   RELATIVE
	; RELATIVEだけはインストラクション処理の途中で呼ばれることがあるので、
	; %r12-15や、その他の一般レジスタもなるべく破壊したくありません。
	; そこで、ext33のワークレジスタ%r9を使います。
	; RELATIVEの実装に、ext33の拡張命令(xldとか)を使わないよう、気をつけてください。
	ld.b %r9, [%r1]+		; tmp = (char)*PC++
	ext spc2ram@ah			; PC = &spc2ram[(unsigned short)(PC - spc2ram + tmp)]
	ext spc2ram@al
	sub %r1, %r1
	add %r1, %r9
	ld.uh %r1, %r1
	ext spc2ram@ah
	ext spc2ram@al
	add %r1, %r1
	ret				; }

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

;============================================================================
;	1. 8-BIT DATA TRANSMISSION COMMANDS GROUP 1
;============================================================================

	.global spc2cpu_0xE8
spc2cpu_0xE8: ; MOV A,#inm
	ld.ub %r12, [%r1]+		; inm = *PC++	; 	INMEDIATE_DATA
	ext	0x6		; 	xld.b [%r0+0x6], %r12
	ld.b	[%r0],%r12
	ext	0x2		; 	xld.b [%r0+0x2], %r12
	ld.b	[%r0],%r12
	ret

	.global spc2cpu_0xE6
spc2cpu_0xE6: ; MOV A,(X)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | X	; 	INDIRECT
	ext	0x5		; 	xld.ub %r12, [%r0+0x5]
	ld.ub	%r12,[%r0]
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x6		; 	xld.b [%r0+0x6], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xBF
spc2cpu_0xBF: ; MOV A,(X)+
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | X++	; 	INDIRECT_AUTO_INCREMENT
	ext	0x5		; 	xld.ub %r12, [%r0+0x5]
	ld.ub	%r12,[%r0]
	ext	0x1		; 	xadd %r13, %r12, 1
	add	%r13,%r12
	ext	0x5		; 	xld.b [%r0+0x5], %r13
	ld.b	[%r0],%r13
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x6		; 	xld.b [%r0+0x6], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xE4
spc2cpu_0xE4: ; MOV A,dp
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x6		; 	xld.b [%r0+0x6], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xF4
spc2cpu_0xF4: ; MOV A,dp+X
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x6		; 	xld.b [%r0+0x6], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xE5
spc2cpu_0xE5: ; MOV A,labs
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x6		; 	xld.b [%r0+0x6], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xF5
spc2cpu_0xF5: ; MOV A,labs+X
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	X_INDEXED_ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	ext	0x5		; 	xld.ub %r14, [%r0+0x5]		; mem  = (unsigned short)(mem + X)
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x6		; 	xld.b [%r0+0x6], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xF6
spc2cpu_0xF6: ; MOV A,labs+Y
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	Y_INDEXED_ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	ext	0x7		; 	xld.ub %r14, [%r0+0x7]		; mem  = (unsigned short)(mem + Y)
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x6		; 	xld.b [%r0+0x6], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xE7
spc2cpu_0xE7: ; MOV A,(dp+X)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_INDIRECT
	ld.ub %r13, [%r1]+
	ext	0x5		; 	xld.ub %r14, [%r0+0x5]
	ld.ub	%r14,[%r0]
	add %r13, %r14
	ld.ub %r13, %r13
	or %r13, %r15
	ext spc2ram@ah			; mem = spc2ram[mem] | spc2ram[mem + 1] << 8
	ext spc2ram@al
	add %r13, %r13
	ld.ub %r12, [%r13]+
	ld.ub %r13, [%r13]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x6		; 	xld.b [%r0+0x6], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xF7
spc2cpu_0xF7: ; MOV A,(dp)+Y
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	INDIRECT_Y_INDEXED_INDIRECT
	ld.ub %r13, [%r1]+
	or %r13, %r15
	ext spc2ram@ah			; mem = spc2ram[mem] | spc2ram[mem + 1] << 8
	ext spc2ram@al			; mem = (unsigned short)(mem + Y)
	add %r13, %r13
	ld.ub %r12, [%r13]+
	ld.ub %r13, [%r13]
	ext	0x7		; 	xld.ub %r14, [%r0+0x7]
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x6		; 	xld.b [%r0+0x6], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xCD
spc2cpu_0xCD: ; MOV X,#inm
	ld.ub %r12, [%r1]+		; inm = *PC++	; 	INMEDIATE_DATA
	ext	0x5		; 	xld.b [%r0+0x5], %r12
	ld.b	[%r0],%r12
	ext	0x2		; 	xld.b [%r0+0x2], %r12
	ld.b	[%r0],%r12
	ret

	.global spc2cpu_0xF8
spc2cpu_0xF8: ; MOV X,dp
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x5		; 	xld.b [%r0+0x5], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xF9
spc2cpu_0xF9: ; MOV X,dp+Y
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + Y)	; 	Y_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x7		; 	xld.ub %r13, [%r0+0x7]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x5		; 	xld.b [%r0+0x5], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xE9
spc2cpu_0xE9: ; MOV X,labs
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x5		; 	xld.b [%r0+0x5], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0x8D
spc2cpu_0x8D: ; MOV Y,#inm
	ld.ub %r12, [%r1]+		; inm = *PC++	; 	INMEDIATE_DATA
	ext	0x7		; 	xld.b [%r0+0x7], %r12
	ld.b	[%r0],%r12
	ext	0x2		; 	xld.b [%r0+0x2], %r12
	ld.b	[%r0],%r12
	ret

	.global spc2cpu_0xEB
spc2cpu_0xEB: ; MOV Y,dp
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x7		; 	xld.b [%r0+0x7], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xFB
spc2cpu_0xFB: ; MOV Y,dp+X
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x7		; 	xld.b [%r0+0x7], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xEC
spc2cpu_0xEC: ; MOV Y,labs
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x7		; 	xld.b [%r0+0x7], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

;============================================================================
;	2. 8-BIT DATA TRANSMISSION COMMANDS GROUP 2
;============================================================================

	.global spc2cpu_0xC6
spc2cpu_0xC6: ; MOV (X),A
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | X	; 	INDIRECT
	ext	0x5		; 	xld.ub %r12, [%r0+0x5]
	ld.ub	%r12,[%r0]
	or %r12, %r15
	ext	0x6		; 	xld.ub %r13, [%r0+0x6]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xAF
spc2cpu_0xAF: ; MOV (X)+,A
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | X++	; 	INDIRECT_AUTO_INCREMENT
	ext	0x5		; 	xld.ub %r12, [%r0+0x5]
	ld.ub	%r12,[%r0]
	ext	0x1		; 	xadd %r13, %r12, 1
	add	%r13,%r12
	ext	0x5		; 	xld.b [%r0+0x5], %r13
	ld.b	[%r0],%r13
	or %r12, %r15
	ext	0x6		; 	xld.ub %r13, [%r0+0x6]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xC4
spc2cpu_0xC4: ; MOV dp,A
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	0x6		; 	xld.ub %r13, [%r0+0x6]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xD4
spc2cpu_0xD4: ; MOV dp+X,A
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	0x6		; 	xld.ub %r13, [%r0+0x6]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xC5
spc2cpu_0xC5: ; MOV labs,A
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	0x6		; 	xld.ub %r13, [%r0+0x6]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xD5
spc2cpu_0xD5: ; MOV labs+X,A
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	X_INDEXED_ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	ext	0x5		; 	xld.ub %r14, [%r0+0x5]		; mem  = (unsigned short)(mem + X)
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	0x6		; 	xld.ub %r13, [%r0+0x6]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xD6
spc2cpu_0xD6: ; MOV labs+Y,A
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	Y_INDEXED_ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	ext	0x7		; 	xld.ub %r14, [%r0+0x7]		; mem  = (unsigned short)(mem + Y)
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	0x6		; 	xld.ub %r13, [%r0+0x6]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xC7
spc2cpu_0xC7: ; MOV (dp+X),A
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_INDIRECT
	ld.ub %r13, [%r1]+
	ext	0x5		; 	xld.ub %r14, [%r0+0x5]
	ld.ub	%r14,[%r0]
	add %r13, %r14
	ld.ub %r13, %r13
	or %r13, %r15
	ext spc2ram@ah			; mem = spc2ram[mem] | spc2ram[mem + 1] << 8
	ext spc2ram@al
	add %r13, %r13
	ld.ub %r12, [%r13]+
	ld.ub %r13, [%r13]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	0x6		; 	xld.ub %r13, [%r0+0x6]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xD7
spc2cpu_0xD7: ; MOV (dp)+Y,A
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	INDIRECT_Y_INDEXED_INDIRECT
	ld.ub %r13, [%r1]+
	or %r13, %r15
	ext spc2ram@ah			; mem = spc2ram[mem] | spc2ram[mem + 1] << 8
	ext spc2ram@al			; mem = (unsigned short)(mem + Y)
	add %r13, %r13
	ld.ub %r12, [%r13]+
	ld.ub %r13, [%r13]
	ext	0x7		; 	xld.ub %r14, [%r0+0x7]
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	0x6		; 	xld.ub %r13, [%r0+0x6]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xD8
spc2cpu_0xD8: ; MOV dp,X
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xD9
spc2cpu_0xD9: ; MOV dp+Y,X
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + Y)	; 	Y_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x7		; 	xld.ub %r13, [%r0+0x7]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xC9
spc2cpu_0xC9: ; MOV labs,X
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xCB
spc2cpu_0xCB: ; MOV dp,Y
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	0x7		; 	xld.ub %r13, [%r0+0x7]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xDB
spc2cpu_0xDB: ; MOV dp+X,Y
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	0x7		; 	xld.ub %r13, [%r0+0x7]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xCC
spc2cpu_0xCC: ; MOV labs,Y
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	0x7		; 	xld.ub %r13, [%r0+0x7]
	ld.ub	%r13,[%r0]
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

;============================================================================
;	3. 8-BIT DATA TRANSMISSIN COMMANDS GROUP 3
;============================================================================

	.global spc2cpu_0x7D
spc2cpu_0x7D: ; MOV A,X
	ext	0x5		; 	xld.ub %r10, [%r0+0x5]
	ld.ub	%r10,[%r0]
	ext	0x6		; 	xld.b [%r0+0x6], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xDD
spc2cpu_0xDD: ; MOV A,Y
	ext	0x7		; 	xld.ub %r10, [%r0+0x7]
	ld.ub	%r10,[%r0]
	ext	0x6		; 	xld.b [%r0+0x6], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0x5D
spc2cpu_0x5D: ; MOV X,A
	ext	0x6		; 	xld.ub %r10, [%r0+0x6]
	ld.ub	%r10,[%r0]
	ext	0x5		; 	xld.b [%r0+0x5], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xFD
spc2cpu_0xFD: ; MOV Y,A
	ext	0x6		; 	xld.ub %r10, [%r0+0x6]
	ld.ub	%r10,[%r0]
	ext	0x7		; 	xld.b [%r0+0x7], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0x9D
spc2cpu_0x9D: ; MOV X,SP
	ext	0x8		; 	xld.w %r10, [%r0+0x8]
	ld.w	%r10,[%r0]
	ext spc2ram+0x100@ah
	ext spc2ram+0x100@al
	sub %r10, %r10
	ext	0x5		; 	xld.b [%r0+0x5], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

	.global spc2cpu_0xBD
spc2cpu_0xBD: ; MOV SP,X
	ext	0x5		; 	xld.ub %r10, [%r0+0x5]
	ld.ub	%r10,[%r0]
	ext spc2ram+0x100@ah
	ext spc2ram+0x100@al
	add %r10, %r10
	ext	0x8		; 	xld.w [%r0+0x8], %r10
	ld.w	[%r0],%r10
	ret

	.global spc2cpu_0xFA
spc2cpu_0xFA: ; MOV dp(d),dp(s)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; 	DIRECT_PAGE_TO_DP
	ld.ub %r12, [%r1]+		; src = PSW_P | *PC++
	ld.ub %r13, [%r1]+		; dst = PSW_P | *PC++
	or %r12, %r15
	or %r13, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r12, %r13
	ld.w %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0x8F
spc2cpu_0x8F: ; MOV dp,#inm
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; 	INMEDIATE_DATA_TO_DP
	ld.ub %r12, [%r1]+		; inm = *PC++
	ld.ub %r13, [%r1]+		; mem = PSW_P | *PC++
	or %r13, %r15
	ld.w %r10, %r12
	ld.w %r12, %r13
	ld.w %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

;============================================================================
;	5. 8-BIT LOGIC OPERATION COMMANDS
;============================================================================

	.global spc2cpu_0x28
spc2cpu_0x28: ; AND A,#inm
	ld.ub %r12, [%r1]+		; inm = *PC++	; 	INMEDIATE_DATA
	ld.w %r15, %r12
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	and %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x26
spc2cpu_0x26: ; AND A,(X)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | X	; 	INDIRECT
	ext	0x5		; 	xld.ub %r12, [%r0+0x5]
	ld.ub	%r12,[%r0]
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	and %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x24
spc2cpu_0x24: ; AND A,dp
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	and %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x34
spc2cpu_0x34: ; AND A,dp+X
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	and %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x25
spc2cpu_0x25: ; AND A,labs
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	and %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x35
spc2cpu_0x35: ; AND A,labs+X
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	X_INDEXED_ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	ext	0x5		; 	xld.ub %r14, [%r0+0x5]		; mem  = (unsigned short)(mem + X)
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	and %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x36
spc2cpu_0x36: ; AND A,labs+Y
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	Y_INDEXED_ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	ext	0x7		; 	xld.ub %r14, [%r0+0x7]		; mem  = (unsigned short)(mem + Y)
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	and %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x27
spc2cpu_0x27: ; AND A,(dp+X)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_INDIRECT
	ld.ub %r13, [%r1]+
	ext	0x5		; 	xld.ub %r14, [%r0+0x5]
	ld.ub	%r14,[%r0]
	add %r13, %r14
	ld.ub %r13, %r13
	or %r13, %r15
	ext spc2ram@ah			; mem = spc2ram[mem] | spc2ram[mem + 1] << 8
	ext spc2ram@al
	add %r13, %r13
	ld.ub %r12, [%r13]+
	ld.ub %r13, [%r13]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	and %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x37
spc2cpu_0x37: ; AND A,(dp)+Y
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	INDIRECT_Y_INDEXED_INDIRECT
	ld.ub %r13, [%r1]+
	or %r13, %r15
	ext spc2ram@ah			; mem = spc2ram[mem] | spc2ram[mem + 1] << 8
	ext spc2ram@al			; mem = (unsigned short)(mem + Y)
	add %r13, %r13
	ld.ub %r12, [%r13]+
	ld.ub %r13, [%r13]
	ext	0x7		; 	xld.ub %r14, [%r0+0x7]
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	and %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x39
spc2cpu_0x39: ; AND (X),(Y)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; 	INDIRECT_PAGE_TO_IP
	ext	0x7		; 	xld.ub %r12, [%r0+0x7]		; src = PSW_P | Y
	ld.ub	%r12,[%r0]
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]		; dst = PSW_P | X
	ld.ub	%r13,[%r0]
	or %r12, %r15
	or %r13, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r14, %r10
	and %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x29
spc2cpu_0x29: ; AND dp(d),dp(s)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; 	DIRECT_PAGE_TO_DP
	ld.ub %r12, [%r1]+		; src = PSW_P | *PC++
	ld.ub %r13, [%r1]+		; dst = PSW_P | *PC++
	or %r12, %r15
	or %r13, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r12, %r13
	ld.w %r13, %r10
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	and %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

	.global spc2cpu_0x38
spc2cpu_0x38: ; AND dp,#inm
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; 	INMEDIATE_DATA_TO_DP
	ld.ub %r12, [%r1]+		; inm = *PC++
	ld.ub %r13, [%r1]+		; mem = PSW_P | *PC++
	or %r13, %r15
	ld.w %r10, %r12
	ld.w %r12, %r13
	ld.w %r13, %r10
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	and %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

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

	.global spc2cpu_0x08
spc2cpu_0x08: ; OR A,#inm
	ld.ub %r12, [%r1]+		; inm = *PC++	; 	INMEDIATE_DATA
	ld.w %r15, %r12
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	or %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x06
spc2cpu_0x06: ; OR A,(X)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | X	; 	INDIRECT
	ext	0x5		; 	xld.ub %r12, [%r0+0x5]
	ld.ub	%r12,[%r0]
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	or %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x04
spc2cpu_0x04: ; OR A,dp
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	or %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x14
spc2cpu_0x14: ; OR A,dp+X
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	or %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x05
spc2cpu_0x05: ; OR A,labs
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	or %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x15
spc2cpu_0x15: ; OR A,labs+X
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	X_INDEXED_ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	ext	0x5		; 	xld.ub %r14, [%r0+0x5]		; mem  = (unsigned short)(mem + X)
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	or %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x16
spc2cpu_0x16: ; OR A,labs+Y
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	Y_INDEXED_ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	ext	0x7		; 	xld.ub %r14, [%r0+0x7]		; mem  = (unsigned short)(mem + Y)
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	or %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x07
spc2cpu_0x07: ; OR A,(dp+X)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_INDIRECT
	ld.ub %r13, [%r1]+
	ext	0x5		; 	xld.ub %r14, [%r0+0x5]
	ld.ub	%r14,[%r0]
	add %r13, %r14
	ld.ub %r13, %r13
	or %r13, %r15
	ext spc2ram@ah			; mem = spc2ram[mem] | spc2ram[mem + 1] << 8
	ext spc2ram@al
	add %r13, %r13
	ld.ub %r12, [%r13]+
	ld.ub %r13, [%r13]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	or %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x17
spc2cpu_0x17: ; OR A,(dp)+Y
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	INDIRECT_Y_INDEXED_INDIRECT
	ld.ub %r13, [%r1]+
	or %r13, %r15
	ext spc2ram@ah			; mem = spc2ram[mem] | spc2ram[mem + 1] << 8
	ext spc2ram@al			; mem = (unsigned short)(mem + Y)
	add %r13, %r13
	ld.ub %r12, [%r13]+
	ld.ub %r13, [%r13]
	ext	0x7		; 	xld.ub %r14, [%r0+0x7]
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	or %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x19
spc2cpu_0x19: ; OR (X),(Y)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; 	INDIRECT_PAGE_TO_IP
	ext	0x7		; 	xld.ub %r12, [%r0+0x7]		; src = PSW_P | Y
	ld.ub	%r12,[%r0]
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]		; dst = PSW_P | X
	ld.ub	%r13,[%r0]
	or %r12, %r15
	or %r13, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r14, %r10
	or %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x09
spc2cpu_0x09: ; OR dp(d),dp(s)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; 	DIRECT_PAGE_TO_DP
	ld.ub %r12, [%r1]+		; src = PSW_P | *PC++
	ld.ub %r13, [%r1]+		; dst = PSW_P | *PC++
	or %r12, %r15
	or %r13, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r12, %r13
	ld.w %r13, %r10
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	or %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

	.global spc2cpu_0x18
spc2cpu_0x18: ; OR dp,#inm
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; 	INMEDIATE_DATA_TO_DP
	ld.ub %r12, [%r1]+		; inm = *PC++
	ld.ub %r13, [%r1]+		; mem = PSW_P | *PC++
	or %r13, %r15
	ld.w %r10, %r12
	ld.w %r12, %r13
	ld.w %r13, %r10
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	or %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

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

	.global spc2cpu_0x48
spc2cpu_0x48: ; EOR A,#inm
	ld.ub %r12, [%r1]+		; inm = *PC++	; 	INMEDIATE_DATA
	ld.w %r15, %r12
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	xor %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x46
spc2cpu_0x46: ; EOR A,(X)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | X	; 	INDIRECT
	ext	0x5		; 	xld.ub %r12, [%r0+0x5]
	ld.ub	%r12,[%r0]
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	xor %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x44
spc2cpu_0x44: ; EOR A,dp
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	xor %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x54
spc2cpu_0x54: ; EOR A,dp+X
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	xor %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x45
spc2cpu_0x45: ; EOR A,labs
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	xor %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x55
spc2cpu_0x55: ; EOR A,labs+X
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	X_INDEXED_ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	ext	0x5		; 	xld.ub %r14, [%r0+0x5]		; mem  = (unsigned short)(mem + X)
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	xor %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x56
spc2cpu_0x56: ; EOR A,labs+Y
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	Y_INDEXED_ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	ext	0x7		; 	xld.ub %r14, [%r0+0x7]		; mem  = (unsigned short)(mem + Y)
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	xor %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x47
spc2cpu_0x47: ; EOR A,(dp+X)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_INDIRECT
	ld.ub %r13, [%r1]+
	ext	0x5		; 	xld.ub %r14, [%r0+0x5]
	ld.ub	%r14,[%r0]
	add %r13, %r14
	ld.ub %r13, %r13
	or %r13, %r15
	ext spc2ram@ah			; mem = spc2ram[mem] | spc2ram[mem + 1] << 8
	ext spc2ram@al
	add %r13, %r13
	ld.ub %r12, [%r13]+
	ld.ub %r13, [%r13]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	xor %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x57
spc2cpu_0x57: ; EOR A,(dp)+Y
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	INDIRECT_Y_INDEXED_INDIRECT
	ld.ub %r13, [%r1]+
	or %r13, %r15
	ext spc2ram@ah			; mem = spc2ram[mem] | spc2ram[mem + 1] << 8
	ext spc2ram@al			; mem = (unsigned short)(mem + Y)
	add %r13, %r13
	ld.ub %r12, [%r13]+
	ld.ub %r13, [%r13]
	ext	0x7		; 	xld.ub %r14, [%r0+0x7]
	ld.ub	%r14,[%r0]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	add %r12, %r14
	ld.uh %r12, %r12
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	0x6		; 	xld.ub %r14, [%r0+0x6]
	ld.ub	%r14,[%r0]
	xor %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x59
spc2cpu_0x59: ; EOR (X),(Y)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; 	INDIRECT_PAGE_TO_IP
	ext	0x7		; 	xld.ub %r12, [%r0+0x7]		; src = PSW_P | Y
	ld.ub	%r12,[%r0]
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]		; dst = PSW_P | X
	ld.ub	%r13,[%r0]
	or %r12, %r15
	or %r13, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r15, %r10
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r14, %r10
	xor %r14, %r15
	ext	0x6		; 	xld.b [%r0+0x6], %r14
	ld.b	[%r0],%r14
	ext	0x2		; 	xld.b [%r0+0x2], %r14
	ld.b	[%r0],%r14
	ret

	.global spc2cpu_0x49
spc2cpu_0x49: ; EOR dp(d),dp(s)
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; 	DIRECT_PAGE_TO_DP
	ld.ub %r12, [%r1]+		; src = PSW_P | *PC++
	ld.ub %r13, [%r1]+		; dst = PSW_P | *PC++
	or %r12, %r15
	or %r13, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r12, %r13
	ld.w %r13, %r10
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	xor %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

	.global spc2cpu_0x58
spc2cpu_0x58: ; EOR dp,#inm
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; 	INMEDIATE_DATA_TO_DP
	ld.ub %r12, [%r1]+		; inm = *PC++
	ld.ub %r13, [%r1]+		; mem = PSW_P | *PC++
	or %r13, %r15
	ld.w %r10, %r12
	ld.w %r12, %r13
	ld.w %r13, %r10
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	xor %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

;============================================================================
;	7. SHIFT, ROTATION COMMANDS
;============================================================================

	.global spc2cpu_0x1C
spc2cpu_0x1C: ; ASL A
	ext	0x6		; 	xld.ub %r13, [%r0+0x6]
	ld.ub	%r13,[%r0]
	sll	%r13,0x1	; 	xsll %r13, 1
	ext	0x6		; 	xld.b [%r0+0x6], %r13
	ld.b	[%r0],%r13
	ext	0x2		; 	xld.h [%r0+0x2], %r13
	ld.h	[%r0],%r13
	ret

	.global spc2cpu_0x0B
spc2cpu_0x0B: ; ASL dp
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r13, %r10
	sll	%r13,0x1	; 	xsll %r13, 1
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.h [%r0+0x2], %r13
	ld.h	[%r0],%r13
	ret

	.global spc2cpu_0x1B
spc2cpu_0x1B: ; ASL dp+X
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r13, %r10
	sll	%r13,0x1	; 	xsll %r13, 1
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.h [%r0+0x2], %r13
	ld.h	[%r0],%r13
	ret

	.global spc2cpu_0x0C
spc2cpu_0x0C: ; ASL labs
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r13, %r10
	sll	%r13,0x1	; 	xsll %r13, 1
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.h [%r0+0x2], %r13
	ld.h	[%r0],%r13
	ret

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

	.global spc2cpu_0x5C
spc2cpu_0x5C: ; LSR A
	ext	0x6		; 	xld.ub %r13, [%r0+0x6]
	ld.ub	%r13,[%r0]
	ext	0x3		; 	xld.b [%r0+0x3], %r13
	ld.b	[%r0],%r13
	srl	%r13,0x1	; 	xsrl %r13, 1
	ext	0x6		; 	xld.b [%r0+0x6], %r13
	ld.b	[%r0],%r13
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

	.global spc2cpu_0x4B
spc2cpu_0x4B: ; LSR dp
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r13, %r10
	ext	0x3		; 	xld.b [%r0+0x3], %r13
	ld.b	[%r0],%r13
	srl	%r13,0x1	; 	xsrl %r13, 1
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

	.global spc2cpu_0x5B
spc2cpu_0x5B: ; LSR dp+X
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r13, %r10
	ext	0x3		; 	xld.b [%r0+0x3], %r13
	ld.b	[%r0],%r13
	srl	%r13,0x1	; 	xsrl %r13, 1
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

	.global spc2cpu_0x4C
spc2cpu_0x4C: ; LSR labs
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r13, %r10
	ext	0x3		; 	xld.b [%r0+0x3], %r13
	ld.b	[%r0],%r13
	srl	%r13,0x1	; 	xsrl %r13, 1
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

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

	.global spc2cpu_0x3C
spc2cpu_0x3C: ; ROL A
	ext	0x6		; 	xld.ub %r13, [%r0+0x6]
	ld.ub	%r13,[%r0]
	sll	%r13,0x1	; 	xsll %r13, 1
	ext	0x3		; 	xld.ub %r10, [%r0+0x3]
	ld.ub	%r10,[%r0]
	and	%r10,0x1	; 	xand %r10, %r10, 1
	or %r13, %r10
	ext	0x6		; 	xld.b [%r0+0x6], %r13
	ld.b	[%r0],%r13
	ext	0x2		; 	xld.h [%r0+0x2], %r13
	ld.h	[%r0],%r13
	ret

	.global spc2cpu_0x2B
spc2cpu_0x2B: ; ROL dp
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r13, %r10
	sll	%r13,0x1	; 	xsll %r13, 1
	ext	0x3		; 	xld.ub %r10, [%r0+0x3]
	ld.ub	%r10,[%r0]
	and	%r10,0x1	; 	xand %r10, %r10, 1
	or %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.h [%r0+0x2], %r13
	ld.h	[%r0],%r13
	ret

	.global spc2cpu_0x3B
spc2cpu_0x3B: ; ROL dp+X
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r13, %r10
	sll	%r13,0x1	; 	xsll %r13, 1
	ext	0x3		; 	xld.ub %r10, [%r0+0x3]
	ld.ub	%r10,[%r0]
	and	%r10,0x1	; 	xand %r10, %r10, 1
	or %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.h [%r0+0x2], %r13
	ld.h	[%r0],%r13
	ret

	.global spc2cpu_0x2C
spc2cpu_0x2C: ; ROL labs
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ld.w %r13, %r10
	sll	%r13,0x1	; 	xsll %r13, 1
	ext	0x3		; 	xld.ub %r10, [%r0+0x3]
	ld.ub	%r10,[%r0]
	and	%r10,0x1	; 	xand %r10, %r10, 1
	or %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.h [%r0+0x2], %r13
	ld.h	[%r0],%r13
	ret

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

	.global spc2cpu_0x7C
spc2cpu_0x7C: ; ROR A
	ext	0x6		; 	xld.ub %r10, [%r0+0x6]
	ld.ub	%r10,[%r0]
	ext	0x3		; 	xld.ub %r13, [%r0+0x3]
	ld.ub	%r13,[%r0]
	ext	0x3		; 	xld.b [%r0+0x3], %r10
	ld.b	[%r0],%r10
	srl	%r10,0x1	; 	xsrl %r10, 1
	sll	%r13,0x7	; 	xsll %r13, 7
	or %r13, %r10
	ext	0x6		; 	xld.b [%r0+0x6], %r13
	ld.b	[%r0],%r13
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

	.global spc2cpu_0x6B
spc2cpu_0x6B: ; ROR dp
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x3		; 	xld.ub %r13, [%r0+0x3]
	ld.ub	%r13,[%r0]
	ext	0x3		; 	xld.b [%r0+0x3], %r10
	ld.b	[%r0],%r10
	srl	%r10,0x1	; 	xsrl %r10, 1
	sll	%r13,0x7	; 	xsll %r13, 7
	or %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

	.global spc2cpu_0x7B
spc2cpu_0x7B: ; ROR dp+X
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x3		; 	xld.ub %r13, [%r0+0x3]
	ld.ub	%r13,[%r0]
	ext	0x3		; 	xld.b [%r0+0x3], %r10
	ld.b	[%r0],%r10
	srl	%r10,0x1	; 	xsrl %r10, 1
	sll	%r13,0x7	; 	xsll %r13, 7
	or %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

	.global spc2cpu_0x6C
spc2cpu_0x6C: ; ROR labs
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x3		; 	xld.ub %r13, [%r0+0x3]
	ld.ub	%r13,[%r0]
	ext	0x3		; 	xld.b [%r0+0x3], %r10
	ld.b	[%r0],%r10
	srl	%r10,0x1	; 	xsrl %r10, 1
	sll	%r13,0x7	; 	xsll %r13, 7
	or %r13, %r10
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ext	0x2		; 	xld.b [%r0+0x2], %r13
	ld.b	[%r0],%r13
	ret

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

	.global spc2cpu_0x9F
spc2cpu_0x9F: ; XCN A
	ext	0x6		; 	xld.ub %r10, [%r0+0x6]
	ld.ub	%r10,[%r0]
	ld.w %r11, %r10
	srl	%r10,0x4	; 	xsrl %r10, 4
	sll	%r11,0x4	; 	xsll %r11, 4
	or %r10, %r11
	ext	0x6		; 	xld.b [%r0+0x6], %r10
	ld.b	[%r0],%r10
	ext	0x2		; 	xld.b [%r0+0x2], %r10
	ld.b	[%r0],%r10
	ret

;============================================================================
;	12. BRANCHING COMMANDS
;============================================================================

	.global spc2cpu_0x2F
spc2cpu_0x2F: ; BRA rel
	; 他のアドレッシングモードがインストラクション処理の先頭だけで呼ばれるのに対し、	; 	RELATIVE
	; RELATIVEだけはインストラクション処理の途中で呼ばれることがあるので、
	; %r12-15や、その他の一般レジスタもなるべく破壊したくありません。
	; そこで、ext33のワークレジスタ%r9を使います。
	; RELATIVEの実装に、ext33の拡張命令(xldとか)を使わないよう、気をつけてください。
	ld.b %r9, [%r1]+		; tmp = (char)*PC++
	ext spc2ram@ah			; PC = &spc2ram[(unsigned short)(PC - spc2ram + tmp)]
	ext spc2ram@al
	sub %r1, %r1
	add %r1, %r9
	ld.uh %r1, %r1
	ext spc2ram@ah
	ext spc2ram@al
	add %r1, %r1
	ret

	.global spc2cpu_0xF0
spc2cpu_0xF0: ; BEQ rel
	ext	0x2		; 	xld.ub %r10, [%r0+0x2]
	ld.ub	%r10,[%r0]
	cmp	%r10,0x0	; 	xcmp %r10, 0
	ext	spc2cpu_BEQ@rm	; 	xcall spc2cpu_BEQ	; 	BEQ
	call	spc2cpu_BEQ@rl
	ret

	.global spc2cpu_0xD0
spc2cpu_0xD0: ; BNE rel
	ext	0x2		; 	xld.ub %r10, [%r0+0x2]
	ld.ub	%r10,[%r0]
	cmp	%r10,0x0	; 	xcmp %r10, 0
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0xB0
spc2cpu_0xB0: ; BCS rel
	ext	0x3		; 	xbtst [%r0+0x3], 0x0
	btst	[%r0],0x0
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0x90
spc2cpu_0x90: ; BCC rel
	ext	0x3		; 	xbtst [%r0+0x3], 0x0
	btst	[%r0],0x0
	ext	spc2cpu_BEQ@rm	; 	xcall spc2cpu_BEQ	; 	BEQ
	call	spc2cpu_BEQ@rl
	ret

	.global spc2cpu_0x70
spc2cpu_0x70: ; BVS rel
	ext	0x4		; 	xbtst [%r0+0x4], 0x7
	btst	[%r0],0x7
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0x50
spc2cpu_0x50: ; BVC rel
	ext	0x4		; 	xbtst [%r0+0x4], 0x7
	btst	[%r0],0x7
	ext	spc2cpu_BEQ@rm	; 	xcall spc2cpu_BEQ	; 	BEQ
	call	spc2cpu_BEQ@rl
	ret

	.global spc2cpu_0x30
spc2cpu_0x30: ; BMI rel
	ext	0x2		; 	xbtst [%r0+0x2], 0x7
	btst	[%r0],0x7
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0x10
spc2cpu_0x10: ; BPL rel
	ext	0x2		; 	xbtst [%r0+0x2], 0x7
	btst	[%r0],0x7
	ext	spc2cpu_BEQ@rm	; 	xcall spc2cpu_BEQ	; 	BEQ
	call	spc2cpu_BEQ@rl
	ret

	.global spc2cpu_0x03
spc2cpu_0x03: ; BBS0 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	and	%r10,0x1	; 	xand %r10, %r10, 0x1
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0x23
spc2cpu_0x23: ; BBS1 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	and	%r10,0x2	; 	xand %r10, %r10, 0x2
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0x43
spc2cpu_0x43: ; BBS2 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	and	%r10,0x4	; 	xand %r10, %r10, 0x4
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0x63
spc2cpu_0x63: ; BBS3 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	and	%r10,0x8	; 	xand %r10, %r10, 0x8
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0x83
spc2cpu_0x83: ; BBS4 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	and	%r10,0x10	; 	xand %r10, %r10, 0x10
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0xA3
spc2cpu_0xA3: ; BBS5 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x0		; 	xand %r10, %r10, 0x20
	and	%r10,0x20
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0xC3
spc2cpu_0xC3: ; BBS6 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x1		; 	xand %r10, %r10, 0x40
	and	%r10,0x0
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0xE3
spc2cpu_0xE3: ; BBS7 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x2		; 	xand %r10, %r10, 0x80
	and	%r10,0x0
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0x13
spc2cpu_0x13: ; BBC0 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	and	%r10,0x1	; 	xand %r10, %r10, 0x1
	ext	spc2cpu_BEQ@rm	; 	xcall spc2cpu_BEQ	; 	BEQ
	call	spc2cpu_BEQ@rl
	ret

	.global spc2cpu_0x33
spc2cpu_0x33: ; BBC1 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	and	%r10,0x2	; 	xand %r10, %r10, 0x2
	ext	spc2cpu_BEQ@rm	; 	xcall spc2cpu_BEQ	; 	BEQ
	call	spc2cpu_BEQ@rl
	ret

	.global spc2cpu_0x53
spc2cpu_0x53: ; BBC2 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	and	%r10,0x4	; 	xand %r10, %r10, 0x4
	ext	spc2cpu_BEQ@rm	; 	xcall spc2cpu_BEQ	; 	BEQ
	call	spc2cpu_BEQ@rl
	ret

	.global spc2cpu_0x73
spc2cpu_0x73: ; BBC3 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	and	%r10,0x8	; 	xand %r10, %r10, 0x8
	ext	spc2cpu_BEQ@rm	; 	xcall spc2cpu_BEQ	; 	BEQ
	call	spc2cpu_BEQ@rl
	ret

	.global spc2cpu_0x93
spc2cpu_0x93: ; BBC4 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	and	%r10,0x10	; 	xand %r10, %r10, 0x10
	ext	spc2cpu_BEQ@rm	; 	xcall spc2cpu_BEQ	; 	BEQ
	call	spc2cpu_BEQ@rl
	ret

	.global spc2cpu_0xB3
spc2cpu_0xB3: ; BBC5 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x0		; 	xand %r10, %r10, 0x20
	and	%r10,0x20
	ext	spc2cpu_BEQ@rm	; 	xcall spc2cpu_BEQ	; 	BEQ
	call	spc2cpu_BEQ@rl
	ret

	.global spc2cpu_0xD3
spc2cpu_0xD3: ; BBC6 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x1		; 	xand %r10, %r10, 0x40
	and	%r10,0x0
	ext	spc2cpu_BEQ@rm	; 	xcall spc2cpu_BEQ	; 	BEQ
	call	spc2cpu_BEQ@rl
	ret

	.global spc2cpu_0xF3
spc2cpu_0xF3: ; BBC7 dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x2		; 	xand %r10, %r10, 0x80
	and	%r10,0x0
	ext	spc2cpu_BEQ@rm	; 	xcall spc2cpu_BEQ	; 	BEQ
	call	spc2cpu_BEQ@rl
	ret

	.global spc2cpu_0x2E
spc2cpu_0x2E: ; CBNE dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x6		; 	xld.ub %r11, [%r0+0x6]
	ld.ub	%r11,[%r0]
	cmp %r11, %r10
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0xDE
spc2cpu_0xDE: ; CBNE dp+X,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | (unsigned char)(*PC++ + X)	; 	X_INDEXED_DIRECT_PAGE
	ld.ub %r12, [%r1]+
	ext	0x5		; 	xld.ub %r13, [%r0+0x5]
	ld.ub	%r13,[%r0]
	add %r12, %r13
	ld.ub %r12, %r12
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x6		; 	xld.ub %r11, [%r0+0x6]
	ld.ub	%r11,[%r0]
	cmp %r11, %r10
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0x6E
spc2cpu_0x6E: ; DBNZ dp,rel
	ld.uh	%r15,[%r0]	; 	xld.uh %r15, [%r0+0x0]	; mem = PSW_P | *PC++	; 	DIRECT_PAGE
	ld.ub %r12, [%r1]+
	or %r12, %r15
	ext	spc2cpu_READ@rm	; 	xcall spc2cpu_READ	; 	READ
	call	spc2cpu_READ@rl
	ext	0x1		; 	xsub %r13, %r10, 1
	sub	%r13,%r10
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ext	spc2cpu_WRITE@rm	; 	xcall spc2cpu_WRITE	; 	WRITE
	call	spc2cpu_WRITE@rl
	ret

	.global spc2cpu_0xFE
spc2cpu_0xFE: ; DBNZ Y,rel
	ext	0x7		; 	xld.ub %r10, [%r0+0x7]
	ld.ub	%r10,[%r0]
	sub	%r10,0x1	; 	xsub %r10, %r10, 1
	ext	0x7		; 	xld.b [%r0+0x7], %r10
	ld.b	[%r0],%r10
	ext	spc2cpu_BNE@rm	; 	xcall spc2cpu_BNE	; 	BNE
	call	spc2cpu_BNE@rl
	ret

	.global spc2cpu_0x5F
spc2cpu_0x5F: ; JMP labs
	ld.ub %r12, [%r1]+		; mem  = *PC++	; 	ABSOLUTE
	ld.ub %r13, [%r1]+		; mem |= *PC++ << 8
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext spc2ram@ah
	ext spc2ram@al
	add %r1, %r12
	ret

	.global spc2cpu_0x1F
spc2cpu_0x1F: ; JMP (labs+X)
	ld.ub %r13, [%r1]+		; mem  = *PC++	; 	X_INDEXED_ABSOLUTE_INDIRECT
	ld.ub %r14, [%r1]+		; mem |= *PC++ << 8
	ext	0x5		; 	xld.ub %r15, [%r0+0x5]		; mem  = (unsigned short)(mem + X)
	ld.ub	%r15,[%r0]
	sll	%r14,0x8	; 	xsll %r14, 8
	or %r13, %r14
	add %r13, %r15
	ld.uh %r13, %r13
	ext spc2ram@ah			; mem  = spc2ram[mem] | spc2ram[mem + 1] << 8
	ext spc2ram@al
	add %r13, %r13
	ld.ub %r12, [%r13]+
	ld.ub %r13, [%r13]
	sll	%r13,0x8	; 	xsll %r13, 8
	or %r12, %r13
	ext spc2ram@ah
	ext spc2ram@al
	add %r1, %r12
	ret

;****************************************************************************
;	SPC2DSP
;****************************************************************************

	.global spc2vce_mix
spc2vce_mix:
	pushn %r3
	sub	%sp,0x2		; 	xsub %sp, %sp, 8
	; %r12 = vce
	; %r13 = mixbuf

	; メインボリューム×チャネルボリューム×エンベロープを求めます。
	ext	spc2dsp+0x0@ah	; 	xld.w %r0, [spc2dsp+0x0]	; vol = (dsp->mvol * vce->vol * (vce->envx >> 16)) >> 13
	ext	spc2dsp+0x0@al
	ld.w	%r0,[%r8]
	ext	0x4		; 	xld.w %r10, [%r12+0x4]
	ld.w	%r10,[%r12]
	ext	0x20		; 	xld.w %r11, [%r12+0x20]
	ld.w	%r11,[%r12]
	mlt.h %r0, %r10
	ld.w %r0, %alr
	srl	%r11,0x8	; 	xsrl %r11, 16
	srl	%r11,0x8
	mlt.h %r0, %r11
	ld.w %r0, %alr
	srl	%r0,0x8		; 	xsrl %r0, 13
	srl	%r0,0x5
	jreq	spc2vce_mix_EXIT	; 	xjreq spc2vce_mix_EXIT		; ボリュームが0か、ほとんどゼロ
	; %r0 = vol

	; 高速化のため、頻繁に使うフィールドを取り出しておきます。
	ext	0x30		; 	xld.w %r1, [%r12+0x30]	; vce->progress
	ld.w	%r1,[%r12]
	ext	0x8		; 	xld.w %r2, [%r12+0x8]		; vce->p
	ld.w	%r2,[%r12]
	; %r1 = progress
	; %r2 = p

	; vce->sampleのベースアドレスも計算しておいた方が速いです。
	; この値はvceから簡単に復元できるので、spc2vce_decode_brr呼び出し時にスタックに保存する必要はありません。
	; vce->pも簡単に復元できるのですが、メモリ読み出しを伴わない分vce->sampleの方が復元コストが安いと考え、
	; vce->pは保存されるレジスタ%r2に、vce->sampleは保存されないレジスタ%r4に置くことにしました。
	ext	0x34		; 	xadd %r4, %r12, 52
	add	%r4,%r12
	; %r4 = sample

	; 同様に、16<<11も頻繁に使うので、レジスタに保持することにします。
	; %r4=sampleと同様、spc2vce_decode_brr呼び出し時はスタックに保存せず、明示的に16<<11を代入して復元します。
	ext	0x200		; 	xld.w %r5, 0x8000
	ld.w	%r5,0x0
	; %r5 = 16<<11

	ext	0x1		; 	xld.w %r3, 64			; for(i = 0; i < 64; i++) {
	ld.w	%r3,0x0
	; %r3 = i
spc2vce_mix_L10:
	add %r1, %r2			; progress += p

spc2vce_mix_L20:
	cmp %r1, %r5			; while(progress >= 16 << 11) {
	jrlt	spc2vce_mix_L30	; 	xjrlt spc2vce_mix_L30
	sub %r1, %r5			; progress -= 16 << 11

	ext	0x2c		; 	xbtst [%r12+0x2c], 0x0	; if(vce->last_loop & 1) { /* 最終ブロック */
	btst	[%r12],0x0
	jreq	spc2vce_mix_L40	; 	xjreq spc2vce_mix_L40
	ext	0x2c		; 	xbtst [%r12+0x2c], 0x1	; if(!(vce->last_loop & 2)) { /* ループしない音色 */
	btst	[%r12],0x1
	jrne	spc2vce_mix_L50	; 	xjrne spc2vce_mix_L50

	ld.w	[%r12],%r8	; 	xld.w [%r12+0x0], %r8		; vce->state = 0
	jp	spc2vce_mix_EXIT	; 	xjp spc2vce_mix_EXIT		; return

spc2vce_mix_L50:			; } else { /* ループ音色 */
	ext	0x24		; 	xld.w %r10, [%r12+0x24]		; vce->brr_addr = vce->lsa
	ld.w	%r10,[%r12]
	ext	0x28		; 	xld.w [%r12+0x28], %r10
	ld.w	[%r12],%r10
	; FALLTHRU

spc2vce_mix_L40:			; } /* if */
	ld.w	[%sp+0x0],%r12	; 	xld.w [%sp+ 0x0], %r12
	ld.w	[%sp+0x1],%r13	; 	xld.w [%sp+ 0x4], %r13
	call	spc2vce_decode_brr	; 	xcall spc2vce_decode_brr	; spc2vce_decode_brr(vce)
	ld.w	%r12,[%sp+0x0]	; 	xld.w %r12, [%sp+ 0x0]
	ld.w	%r13,[%sp+0x1]	; 	xld.w %r13, [%sp+ 0x4]
	ext	0x34		; 	xadd %r4, %r12, 52		; %r4 = sample 復元
	add	%r4,%r12
	ext	0x200		; 	xld.w %r5, 0x8000		; %r5 = 16<<11 復元
	ld.w	%r5,0x0
	jp	spc2vce_mix_L20	; 	xjp spc2vce_mix_L20

spc2vce_mix_L30:			; } /* while */
	ld.w %r10, [%r13]		; *mixbuf
	ld.w %r11, %r1			; sample[progress >> 11]
	srl	%r11,0x8	; 	xsrl %r11, 0xa
	srl	%r11,0x2
	and	%r11,0x3e	; 	xand %r11, %r11, -2
	add %r11, %r4
	ld.h %r11, [%r11]
	mlt.h %r11, %r0			; sample[progress >> 11] * vol
	ld.w %r11, %alr
	add %r10, %r11			; *mixbuf++ += (sample[progress >> 11] * vol)
	ld.w [%r13]+, %r10

	sub	%r3,0x1		; 	xsub %r3, %r3, 1		; } /* for */
	jrne	spc2vce_mix_L10	; 	xjrne spc2vce_mix_L10

	; 進行カウンタ書き戻し。忘れないで!!
	ext	0x30		; 	xld.w [%r12+0x30], %r1	; vce->progress
	ld.w	[%r12],%r1

spc2vce_mix_EXIT:
	add	%sp,0x2		; 	xadd %sp, %sp, 8
	popn %r3
	ret

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

	.global spc2vce_decode_brr
spc2vce_decode_brr:
	pushn %r1
	; %r12 = vce

	; 圧縮データ、展開バッファポインタを取得。
	ext	0x34		; 	xadd %r13, %r12, 52		; dst = vce->sample
	add	%r13,%r12
	ext	0x28		; 	xld.w %r14, [%r12+0x28]	; 先にBRRブロックアドレスを進めておきます。
	ld.w	%r14,[%r12]
	ext	0x9		; 	xadd %r10, %r14, 9
	add	%r10,%r14
	ext	0x28		; 	xld.w [%r12+0x28], %r10
	ld.w	[%r12],%r10
	ext spc2ram@ah			; src = &spc2ram[vce->brr_addr]
	ext spc2ram@al			; (ext33は"xadd %rd,%rs,addr"を展開できない)
	add %r14, %r14
	; %r13 = dst
	; %r14 = src

	; ヘッダ読み出し、格納。
	ld.ub %r15, [%r14]+		; header = *src++
	ext	0x2c		; 	xld.w [%r12+0x2c], %r15	; vce->last_loop = header
	ld.w	[%r12],%r15
	; %r15 = header

	; フィルタ係数取得。
	ext	0xc		; 	xand %r10, %r15, 0xc		; f = spc2dsp_filter_table[(header >> 2) & 3]
	and	%r10,%r15
	ext spc2dsp_filter_table@ah	; (ext33は"xadd %rd,%rs,addr"を展開できない)
	ext spc2dsp_filter_table@al
	add %r10, %r10
	ld.h %r4, [%r10]+		; f1 = f[0]
	ld.h %r5, [%r10]		; f2 = f[1]
	; %r4 = f1
	; %r5 = f1

	; スケーリング係数取得。
	srl	%r15,0x4	; 	xsrl %r15, 4			; range = header >> 4
	; %r15 = range

	ext	0x1e		; 	xld.h %r6, [%r13+0x1e]	; prev1 = vce->sample[16 - 1] /* 1つ前のサンプル */
	ld.h	%r6,[%r13]
	ext	0x1c		; 	xld.h %r7, [%r13+0x1c]	; prev2 = vce->sample[16 - 2] /* 2つ前のサンプル */
	ld.h	%r7,[%r13]
	; %r6 = prev1
	; %r7 = prev2

	ld.w	%r12,0x8	; 	xld.w %r12, 8			; for(i = 0; i < 8; i++) {
	; %r12 = i
spc2vce_decode_brr_L10:

	ld.b %r0, [%r14]+		; ..._ssssssss_hhhhllll,s=h[MSB]
	sll	%r0,0x4		; 	xsll %r0, 4			; ..._sssshhhh_llll0000
	ld.b %r1, %r0			; ..._tttttttt_llll0000,t=l[MSB]
	sra	%r0,0x8		; 	xsra %r0, 8			; ..._ssssssss_sssshhhh => data1 /* 上位ニブルが先 */
	sra	%r1,0x4		; 	xsra %r1, 4			; ..._tttttttt_ttttllll => data2 /* 下位ニブルが後 */
	; %r0 = data1
	; %r1 = data2

	; 先行サンプルを復号。
	mlt.h %r6, %r4			; prev1 * f1
	ld.w %r10, %alr
	mlt.h %r7, %r5			; prev2 * f2
	ld.w %r11, %alr
	sub %r10, %r11			; (prev1 * f1) - (prev2 * f2)
	sra	%r10,0x8	; 	xsra %r10, 8			; ((prev1 * f1) - (prev2 * f2)) >> 8
	ld.w	%r9,%r15	; 	xsll %r0, %r15			; data1 << range
	and	%r9,0x1f
	cmp	%r9,0x8
	jrle	4
	sll	%r0,0x8
	jp.d	-3
	sub	%r9,0x8
	sll	%r0,%r9
	add %r0, %r10			; (data1 << range) + (((prev1 * f1) - (prev2 * f2)) >> 8)
	ext	0x1e00		; 	xcmp %r0, -32767		; if(data1 < -0x7fff) data1 = -0x7fff
	cmp	%r0,0x1
	jrge	spc2vce_decode_brr_L20	; 	xjrge spc2vce_decode_brr_L20
	ext	0x1e00		; 	xld.w %r0, -32767
	ld.w	%r0,0x1
spc2vce_decode_brr_L20:
	ext	0x1ff		; 	xcmp %r0, 0x7fff		; if(data1 >  0x7fff) data1 =  0x7fff
	cmp	%r0,0x3f
	jrle	spc2vce_decode_brr_L30	; 	xjrle spc2vce_decode_brr_L30
	ext	0x1ff		; 	xld.w %r0, 0x7fff
	ld.w	%r0,0x3f
spc2vce_decode_brr_L30:
	ld.h [%r13]+, %r0		; *dst++ = data1
	ld.w %r7, %r6			; prev2 = prev1
	ld.w %r6, %r0			; prev1 = data1

	; 後続サンプルを復号。
	mlt.h %r6, %r4			; prev1 * f1
	ld.w %r10, %alr
	mlt.h %r7, %r5			; prev2 * f2
	ld.w %r11, %alr
	sub %r10, %r11			; (prev1 * f1) - (prev2 * f2)
	sra	%r10,0x8	; 	xsra %r10, 8			; ((prev1 * f1) - (prev2 * f2)) >> 8
	ld.w	%r9,%r15	; 	xsll %r1, %r15			; data2 << range
	and	%r9,0x1f
	cmp	%r9,0x8
	jrle	4
	sll	%r1,0x8
	jp.d	-3
	sub	%r9,0x8
	sll	%r1,%r9
	add %r1, %r10			; (data2 << range) + (((prev1 * f1) - (prev2 * f2)) >> 8)
	ext	0x1e00		; 	xcmp %r1, -32767		; if(data2 < -0x7fff) data2 = -0x7fff
	cmp	%r1,0x1
	jrge	spc2vce_decode_brr_L40	; 	xjrge spc2vce_decode_brr_L40
	ext	0x1e00		; 	xld.w %r1, -32767
	ld.w	%r1,0x1
spc2vce_decode_brr_L40:
	ext	0x1ff		; 	xcmp %r1, 0x7fff		; if(data2 >  0x7fff) data2 =  0x7fff
	cmp	%r1,0x3f
	jrle	spc2vce_decode_brr_L50	; 	xjrle spc2vce_decode_brr_L50
	ext	0x1ff		; 	xld.w %r1, 0x7fff
	ld.w	%r1,0x3f
spc2vce_decode_brr_L50:
	ld.h [%r13]+, %r1		; *dst++ = data2
	ld.w %r7, %r6			; prev2 = prev1
	ld.w %r6, %r1			; prev1 = data2

	sub	%r12,0x1	; 	xsub %r12, %r12, 1		; } /* for */
	jrne	spc2vce_decode_brr_L10	; 	xjrne spc2vce_decode_brr_L10

	popn %r1
	ret

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

;#endif ;/*SPC2_ASM*/
