;
;	clipz8ca.s
;
;	P/ECE Z80 Emulator (高速版)
;
;	CLiP - Common Library for P/ECE
;	Copyright (C) 2001-2005 Naoyuki Sawa
;
;	* Mon Jan 10 19:00:00 JST 2005 Naoyuki Sawa
;	- 作成開始。
;	* Sun Feb 13 03:00:00 JST 2005 Naoyuki Sawa
;	- "ld.ub %rn,[%rn]+"の振る舞いに関するコメント追加。
;	  コードには変更ありません。
;
#include "clipz8ca.h"

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

	.code
	.align 0

;
;	* Z80フラグレジスタ形式から、S1C33 %psrレジスタ形式への変換テーブルです。
;
;	- Z80形式のうち、非公開仕様であるXとYは%psr形式へ変換されません。
;	  X(bit3)およびY(bit5)が0でも1でも、変換結果のC33形式は同じ値になります。
;	  従って、変換前にXとYを0にマスクする必要はありません。
;
;	- C33形式は、C(bit3)、P(bit2)、Z(bit1)、S(bit0)のみを利用します。
;	  C33仕様では符号フラグ(bit0)を"N"と呼びますが、Z80形式と一致させるために、
;	  本モジュールのコメントでは"S"に統一してあります。
;	  以上の4bitに加えて、N(bit5)、H(bit4)を追加しました。
;	  Z80形式の同名ビット(加減算フラグ、ハーフキャリーフラグ)に対応します。
;	  (本当の%psrのbit5-4は、0固定ビットとIEですが、これらは利用しません。)
;
;	- プログラム中で、Nフラグをセットするために、orではなくaddを使っています。
;	  <例>	xoor %F, %F, NF
;		  ではなく
;		xand %F, %F, NF
;	  NF=32なので、or sign6では2命令になってしまいますが、add imm6ならば1命令で済むからです。
;	  NFフラグをセットする前にNFフラグが確実にリセットされている場合は、addを使ってください。
;	  既にNFフラグがセットされている可能性がある場合は、addでは誤った結果になってしまうので、
;	  orを使ってください。
;	  以上の内容は、NFフラグ単独だけではなく、NFを含む複数フラグのセットの場合も同じです。
;	  <例>	xoor %F, %F, NF|HF
;		  ではなく
;		xand %F, %F, NF|HF
;
;	// [テーブルを生成するプログラム]
;	// Z80 Flag-XY    C33 %psr+HC
;	// ----------- => -----------
;	// F(SZ-H-PNC)    F(00NHCPZS)
;	for(i = 0; i < 256; i++) {
;		printf("0x%02x,",
;			((i >> 7) & 1) << 0 | /* S */
;			((i >> 6) & 1) << 1 | /* Z */
;			((i >> 2) & 1) << 2 | /* P */
;			((i >> 0) & 1) << 3 | /* C */
;			((i >> 4) & 1) << 4 | /* H */
;			((i >> 1) & 1) << 5); /* N */
;	}
;
	.global z80cpu_f2psr
z80cpu_f2psr:
	.byte 0x00,0x08,0x20,0x28,0x04,0x0c,0x24,0x2c,0x00,0x08,0x20,0x28,0x04,0x0c,0x24,0x2c
	.byte 0x10,0x18,0x30,0x38,0x14,0x1c,0x34,0x3c,0x10,0x18,0x30,0x38,0x14,0x1c,0x34,0x3c
	.byte 0x00,0x08,0x20,0x28,0x04,0x0c,0x24,0x2c,0x00,0x08,0x20,0x28,0x04,0x0c,0x24,0x2c
	.byte 0x10,0x18,0x30,0x38,0x14,0x1c,0x34,0x3c,0x10,0x18,0x30,0x38,0x14,0x1c,0x34,0x3c
	.byte 0x02,0x0a,0x22,0x2a,0x06,0x0e,0x26,0x2e,0x02,0x0a,0x22,0x2a,0x06,0x0e,0x26,0x2e
	.byte 0x12,0x1a,0x32,0x3a,0x16,0x1e,0x36,0x3e,0x12,0x1a,0x32,0x3a,0x16,0x1e,0x36,0x3e
	.byte 0x02,0x0a,0x22,0x2a,0x06,0x0e,0x26,0x2e,0x02,0x0a,0x22,0x2a,0x06,0x0e,0x26,0x2e
	.byte 0x12,0x1a,0x32,0x3a,0x16,0x1e,0x36,0x3e,0x12,0x1a,0x32,0x3a,0x16,0x1e,0x36,0x3e
	.byte 0x01,0x09,0x21,0x29,0x05,0x0d,0x25,0x2d,0x01,0x09,0x21,0x29,0x05,0x0d,0x25,0x2d
	.byte 0x11,0x19,0x31,0x39,0x15,0x1d,0x35,0x3d,0x11,0x19,0x31,0x39,0x15,0x1d,0x35,0x3d
	.byte 0x01,0x09,0x21,0x29,0x05,0x0d,0x25,0x2d,0x01,0x09,0x21,0x29,0x05,0x0d,0x25,0x2d
	.byte 0x11,0x19,0x31,0x39,0x15,0x1d,0x35,0x3d,0x11,0x19,0x31,0x39,0x15,0x1d,0x35,0x3d
	.byte 0x03,0x0b,0x23,0x2b,0x07,0x0f,0x27,0x2f,0x03,0x0b,0x23,0x2b,0x07,0x0f,0x27,0x2f
	.byte 0x13,0x1b,0x33,0x3b,0x17,0x1f,0x37,0x3f,0x13,0x1b,0x33,0x3b,0x17,0x1f,0x37,0x3f
	.byte 0x03,0x0b,0x23,0x2b,0x07,0x0f,0x27,0x2f,0x03,0x0b,0x23,0x2b,0x07,0x0f,0x27,0x2f
	.byte 0x13,0x1b,0x33,0x3b,0x17,0x1f,0x37,0x3f,0x13,0x1b,0x33,0x3b,0x17,0x1f,0x37,0x3f

;
;	* S1C33 %psrレジスタ形式から、Z80フラグレジスタ形式への変換テーブルです。
;
;	- z80cpu_f2psrのコメントを参照してください。
;
;	- 本モジュールの仕様では、C33形式のbit7-6は0固定でなければいけません。
;	  z80cpu_psr2fのテーブルエントリ数は64しかありません。(bit7-6="00"に依存)
;	  bit7-6のいずれか若しくは両方が1の場合、不正な変換結果になるので注意してください。
;
;	// [テーブルを生成するプログラム]
;	// C33 %psr+HC    Z80 Flag-XY
;	// ----------- => -----------
;	// F(00NHCPZS)    F(SZ-H-PNC)
;	for(i = 0; i < 64; i++) {
;		printf("0x%02x,",
;			((i >> 0) & 1) << 7 | /* S */
;			((i >> 1) & 1) << 6 | /* Z */
;			((i >> 2) & 1) << 2 | /* P */
;			((i >> 3) & 1) << 0 | /* C */
;			((i >> 4) & 1) << 4 | /* H */
;			((i >> 5) & 1) << 1); /* N */
;	}
;
	.global z80cpu_psr2f
z80cpu_psr2f:
	.byte 0x00,0x80,0x40,0xc0,0x04,0x84,0x44,0xc4,0x01,0x81,0x41,0xc1,0x05,0x85,0x45,0xc5
	.byte 0x10,0x90,0x50,0xd0,0x14,0x94,0x54,0xd4,0x11,0x91,0x51,0xd1,0x15,0x95,0x55,0xd5
	.byte 0x02,0x82,0x42,0xc2,0x06,0x86,0x46,0xc6,0x03,0x83,0x43,0xc3,0x07,0x87,0x47,0xc7
	.byte 0x12,0x92,0x52,0xd2,0x16,0x96,0x56,0xd6,0x13,0x93,0x53,0xd3,0x17,0x97,0x57,0xd7

;
;	* 0〜255の1バイト値に対応する、偶数パリティフラグビットの変換表です。
;
;	- パリティフラグビットはZ80形式でもC33形式でも同じ位置(bit2)にありますので、
;	  どちらの用途にも利用可能です。
;	  実際のプログラムでは、C33形式へのマージとして利用しています。
;
	.global z80cpu_parity
z80cpu_parity:
	.byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
	.byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
	.byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
	.byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
	.byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
	.byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
	.byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
	.byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4

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

	.code
	.align 2

	.global z80cpu_XXops
z80cpu_XXops:
	.word z80cpu_NOP		;00
	.word z80cpu_LD_BC_lm		;01
	.word z80cpu_LD_IBCI_A		;02
	.word z80cpu_INC_BC		;03
	.word z80cpu_INC_B		;04
	.word z80cpu_DEC_B		;05
	.word z80cpu_LD_B_n		;06
	.word z80cpu_RLCA		;07
	.word z80cpu_EX_AF_AF2		;08
	.word z80cpu_ADD_HL_BC		;09
	.word z80cpu_LD_A_IBCI		;0A
	.word z80cpu_DEC_BC		;0B
	.word z80cpu_INC_C		;0C
	.word z80cpu_DEC_C		;0D
	.word z80cpu_LD_C_n		;0E
	.word z80cpu_RRCA		;0F
	.word z80cpu_DJNZ_e		;10
	.word z80cpu_LD_DE_lm		;11
	.word z80cpu_LD_IDEI_A		;12
	.word z80cpu_INC_DE		;13
	.word z80cpu_INC_D		;14
	.word z80cpu_DEC_D		;15
	.word z80cpu_LD_D_n		;16
	.word z80cpu_RLA		;17
	.word z80cpu_JR_e		;18
	.word z80cpu_ADD_HL_DE		;19
	.word z80cpu_LD_A_IDEI		;1A
	.word z80cpu_DEC_DE		;1B
	.word z80cpu_INC_E		;1C
	.word z80cpu_DEC_E		;1D
	.word z80cpu_LD_E_n		;1E
	.word z80cpu_RRA		;1F
	.word z80cpu_JR_NZ_e		;20
	.word z80cpu_LD_HL_lm		;21
	.word z80cpu_LD_IlmI_HL		;22
	.word z80cpu_INC_HL		;23
	.word z80cpu_INC_H		;24
	.word z80cpu_DEC_H		;25
	.word z80cpu_LD_H_n		;26
	.word z80cpu_DAA		;27
	.word z80cpu_JR_Z_e		;28
	.word z80cpu_ADD_HL_HL		;29
	.word z80cpu_LD_HL_IlmI		;2A
	.word z80cpu_DEC_HL		;2B
	.word z80cpu_INC_L		;2C
	.word z80cpu_DEC_L		;2D
	.word z80cpu_LD_L_n		;2E
	.word z80cpu_CPL		;2F
	.word z80cpu_JR_NC_e		;30
	.word z80cpu_LD_SP_lm		;31
	.word z80cpu_LD_IlmI_A		;32
	.word z80cpu_INC_SP		;33
	.word z80cpu_INC_IHLI		;34
	.word z80cpu_DEC_IHLI		;35
	.word z80cpu_LD_IHLI_n		;36
	.word z80cpu_SCF		;37
	.word z80cpu_JR_C_e		;38
	.word z80cpu_ADD_HL_SP		;39
	.word z80cpu_LD_A_IlmI		;3A
	.word z80cpu_DEC_SP		;3B
	.word z80cpu_INC_A		;3C
	.word z80cpu_DEC_A		;3D
	.word z80cpu_LD_A_n		;3E
	.word z80cpu_CCF		;3F
	.word z80cpu_LD_B_B		;40
	.word z80cpu_LD_B_C		;41
	.word z80cpu_LD_B_D		;42
	.word z80cpu_LD_B_E		;43
	.word z80cpu_LD_B_H		;44
	.word z80cpu_LD_B_L		;45
	.word z80cpu_LD_B_IHLI		;46
	.word z80cpu_LD_B_A		;47
	.word z80cpu_LD_C_B		;48
	.word z80cpu_LD_C_C		;49
	.word z80cpu_LD_C_D		;4A
	.word z80cpu_LD_C_E		;4B
	.word z80cpu_LD_C_H		;4C
	.word z80cpu_LD_C_L		;4D
	.word z80cpu_LD_C_IHLI		;4E
	.word z80cpu_LD_C_A		;4F
	.word z80cpu_LD_D_B		;50
	.word z80cpu_LD_D_C		;51
	.word z80cpu_LD_D_D		;52
	.word z80cpu_LD_D_E		;53
	.word z80cpu_LD_D_H		;54
	.word z80cpu_LD_D_L		;55
	.word z80cpu_LD_D_IHLI		;56
	.word z80cpu_LD_D_A		;57
	.word z80cpu_LD_E_B		;58
	.word z80cpu_LD_E_C		;59
	.word z80cpu_LD_E_D		;5A
	.word z80cpu_LD_E_E		;5B
	.word z80cpu_LD_E_H		;5C
	.word z80cpu_LD_E_L		;5D
	.word z80cpu_LD_E_IHLI		;5E
	.word z80cpu_LD_E_A		;5F
	.word z80cpu_LD_H_B		;60
	.word z80cpu_LD_H_C		;61
	.word z80cpu_LD_H_D		;62
	.word z80cpu_LD_H_E		;63
	.word z80cpu_LD_H_H		;64
	.word z80cpu_LD_H_L		;65
	.word z80cpu_LD_H_IHLI		;66
	.word z80cpu_LD_H_A		;67
	.word z80cpu_LD_L_B		;68
	.word z80cpu_LD_L_C		;69
	.word z80cpu_LD_L_D		;6A
	.word z80cpu_LD_L_E		;6B
	.word z80cpu_LD_L_H		;6C
	.word z80cpu_LD_L_L		;6D
	.word z80cpu_LD_L_IHLI		;6E
	.word z80cpu_LD_L_A		;6F
	.word z80cpu_LD_IHLI_B		;70
	.word z80cpu_LD_IHLI_C		;71
	.word z80cpu_LD_IHLI_D		;72
	.word z80cpu_LD_IHLI_E		;73
	.word z80cpu_LD_IHLI_H		;74
	.word z80cpu_LD_IHLI_L		;75
	.word z80cpu_HALT		;76
	.word z80cpu_LD_IHLI_A		;77
	.word z80cpu_LD_A_B		;78
	.word z80cpu_LD_A_C		;79
	.word z80cpu_LD_A_D		;7A
	.word z80cpu_LD_A_E		;7B
	.word z80cpu_LD_A_H		;7C
	.word z80cpu_LD_A_L		;7D
	.word z80cpu_LD_A_IHLI		;7E
	.word z80cpu_LD_A_A		;7F
	.word z80cpu_ADD_A_B		;80
	.word z80cpu_ADD_A_C		;81
	.word z80cpu_ADD_A_D		;82
	.word z80cpu_ADD_A_E		;83
	.word z80cpu_ADD_A_H		;84
	.word z80cpu_ADD_A_L		;85
	.word z80cpu_ADD_A_IHLI		;86
	.word z80cpu_ADD_A_A		;87
	.word z80cpu_ADC_A_B		;88
	.word z80cpu_ADC_A_C		;89
	.word z80cpu_ADC_A_D		;8A
	.word z80cpu_ADC_A_E		;8B
	.word z80cpu_ADC_A_H		;8C
	.word z80cpu_ADC_A_L		;8D
	.word z80cpu_ADC_A_IHLI		;8E
	.word z80cpu_ADC_A_A		;8F
	.word z80cpu_SUB_B		;90
	.word z80cpu_SUB_C		;91
	.word z80cpu_SUB_D		;92
	.word z80cpu_SUB_E		;93
	.word z80cpu_SUB_H		;94
	.word z80cpu_SUB_L		;95
	.word z80cpu_SUB_IHLI		;96
	.word z80cpu_SUB_A		;97
	.word z80cpu_SBC_A_B		;98
	.word z80cpu_SBC_A_C		;99
	.word z80cpu_SBC_A_D		;9A
	.word z80cpu_SBC_A_E		;9B
	.word z80cpu_SBC_A_H		;9C
	.word z80cpu_SBC_A_L		;9D
	.word z80cpu_SBC_A_IHLI		;9E
	.word z80cpu_SBC_A_A		;9F
	.word z80cpu_AND_B		;A0
	.word z80cpu_AND_C		;A1
	.word z80cpu_AND_D		;A2
	.word z80cpu_AND_E		;A3
	.word z80cpu_AND_H		;A4
	.word z80cpu_AND_L		;A5
	.word z80cpu_AND_IHLI		;A6
	.word z80cpu_AND_A		;A7
	.word z80cpu_XOR_B		;A8
	.word z80cpu_XOR_C		;A9
	.word z80cpu_XOR_D		;AA
	.word z80cpu_XOR_E		;AB
	.word z80cpu_XOR_H		;AC
	.word z80cpu_XOR_L		;AD
	.word z80cpu_XOR_IHLI		;AE
	.word z80cpu_XOR_A		;AF
	.word z80cpu_OR_B		;B0
	.word z80cpu_OR_C		;B1
	.word z80cpu_OR_D		;B2
	.word z80cpu_OR_E		;B3
	.word z80cpu_OR_H		;B4
	.word z80cpu_OR_L		;B5
	.word z80cpu_OR_IHLI		;B6
	.word z80cpu_OR_A		;B7
	.word z80cpu_CP_B		;B8
	.word z80cpu_CP_C		;B9
	.word z80cpu_CP_D		;BA
	.word z80cpu_CP_E		;BB
	.word z80cpu_CP_H		;BC
	.word z80cpu_CP_L		;BD
	.word z80cpu_CP_IHLI		;BE
	.word z80cpu_CP_A		;BF
	.word z80cpu_RET_NZ		;C0
	.word z80cpu_POP_BC		;C1
	.word z80cpu_JP_NZ_lm		;C2
	.word z80cpu_JP_lm		;C3
	.word z80cpu_CALL_NZ_lm		;C4
	.word z80cpu_PUSH_BC		;C5
	.word z80cpu_ADD_A_n		;C6
	.word z80cpu_RST_00H		;C7
	.word z80cpu_RET_Z		;C8
	.word z80cpu_RET		;C9
	.word z80cpu_JP_Z_lm		;CA
	.word z80cpu_CB			;CB
	.word z80cpu_CALL_Z_lm		;CC
	.word z80cpu_CALL_lm		;CD
	.word z80cpu_ADC_A_n		;CE
	.word z80cpu_RST_08H		;CF
	.word z80cpu_RET_NC		;D0
	.word z80cpu_POP_DE		;D1
	.word z80cpu_JP_NC_lm		;D2
	.word z80cpu_OUT_InI_A		;D3
	.word z80cpu_CALL_NC_lm		;D4
	.word z80cpu_PUSH_DE		;D5
	.word z80cpu_SUB_n		;D6
	.word z80cpu_RST_10H		;D7
	.word z80cpu_RET_C		;D8
	.word z80cpu_EXX		;D9
	.word z80cpu_JP_C_lm		;DA
	.word z80cpu_IN_A_InI		;DB
	.word z80cpu_CALL_C_lm		;DC
	.word z80cpu_DD			;DD
	.word z80cpu_SBC_A_n		;DE
	.word z80cpu_RST_18H		;DF
	.word z80cpu_RET_PO		;E0
	.word z80cpu_POP_HL		;E1
	.word z80cpu_JP_PO_lm		;E2
	.word z80cpu_EX_ISPI_HL		;E3
	.word z80cpu_CALL_PO_lm		;E4
	.word z80cpu_PUSH_HL		;E5
	.word z80cpu_AND_n		;E6
	.word z80cpu_RST_20H		;E7
	.word z80cpu_RET_PE		;E8
	.word z80cpu_JP_IHLI		;E9
	.word z80cpu_JP_PE_lm		;EA
	.word z80cpu_EX_DE_HL		;EB
	.word z80cpu_CALL_PE_lm		;EC
	.word z80cpu_ED			;ED
	.word z80cpu_XOR_n		;EE
	.word z80cpu_RST_28H		;EF
	.word z80cpu_RET_P		;F0
	.word z80cpu_POP_AF		;F1
	.word z80cpu_JP_P_lm		;F2
	.word z80cpu_DI			;F3
	.word z80cpu_CALL_P_lm		;F4
	.word z80cpu_PUSH_AF		;F5
	.word z80cpu_OR_n		;F6
	.word z80cpu_RST_30H		;F7
	.word z80cpu_RET_M		;F8
	.word z80cpu_LD_SP_HL		;F9
	.word z80cpu_JP_M_lm		;FA
	.word z80cpu_EI			;FB
	.word z80cpu_CALL_M_lm		;FC
	.word z80cpu_FD			;FD
	.word z80cpu_CP_n		;FE
	.word z80cpu_RST_38H		;FF

	.global z80cpu_CBops
z80cpu_CBops:
	.word z80cpu_RLC_B		;00
	.word z80cpu_RLC_C		;01
	.word z80cpu_RLC_D		;02
	.word z80cpu_RLC_E		;03
	.word z80cpu_RLC_H		;04
	.word z80cpu_RLC_L		;05
	.word z80cpu_RLC_IHLI		;06
	.word z80cpu_RLC_A		;07
	.word z80cpu_RRC_B		;08
	.word z80cpu_RRC_C		;09
	.word z80cpu_RRC_D		;0A
	.word z80cpu_RRC_E		;0B
	.word z80cpu_RRC_H		;0C
	.word z80cpu_RRC_L		;0D
	.word z80cpu_RRC_IHLI		;0E
	.word z80cpu_RRC_A		;0F
	.word z80cpu_RL_B		;10
	.word z80cpu_RL_C		;11
	.word z80cpu_RL_D		;12
	.word z80cpu_RL_E		;13
	.word z80cpu_RL_H		;14
	.word z80cpu_RL_L		;15
	.word z80cpu_RL_IHLI		;16
	.word z80cpu_RL_A		;17
	.word z80cpu_RR_B		;18
	.word z80cpu_RR_C		;19
	.word z80cpu_RR_D		;1A
	.word z80cpu_RR_E		;1B
	.word z80cpu_RR_H		;1C
	.word z80cpu_RR_L		;1D
	.word z80cpu_RR_IHLI		;1E
	.word z80cpu_RR_A		;1F
	.word z80cpu_SLA_B		;20
	.word z80cpu_SLA_C		;21
	.word z80cpu_SLA_D		;22
	.word z80cpu_SLA_E		;23
	.word z80cpu_SLA_H		;24
	.word z80cpu_SLA_L		;25
	.word z80cpu_SLA_IHLI		;26
	.word z80cpu_SLA_A		;27
	.word z80cpu_SRA_B		;28
	.word z80cpu_SRA_C		;29
	.word z80cpu_SRA_D		;2A
	.word z80cpu_SRA_E		;2B
	.word z80cpu_SRA_H		;2C
	.word z80cpu_SRA_L		;2D
	.word z80cpu_SRA_IHLI		;2E
	.word z80cpu_SRA_A		;2F
	.word z80cpu_ERROR		;30
	.word z80cpu_ERROR		;31
	.word z80cpu_ERROR		;32
	.word z80cpu_ERROR		;33
	.word z80cpu_ERROR		;34
	.word z80cpu_ERROR		;35
	.word z80cpu_ERROR		;36
	.word z80cpu_ERROR		;37
	.word z80cpu_SRL_B		;38
	.word z80cpu_SRL_C		;39
	.word z80cpu_SRL_D		;3A
	.word z80cpu_SRL_E		;3B
	.word z80cpu_SRL_H		;3C
	.word z80cpu_SRL_L		;3D
	.word z80cpu_SRL_IHLI		;3E
	.word z80cpu_SRL_A		;3F
	.word z80cpu_BIT_0_B		;40
	.word z80cpu_BIT_0_C		;41
	.word z80cpu_BIT_0_D		;42
	.word z80cpu_BIT_0_E		;43
	.word z80cpu_BIT_0_H		;44
	.word z80cpu_BIT_0_L		;45
	.word z80cpu_BIT_0_IHLI		;46
	.word z80cpu_BIT_0_A		;47
	.word z80cpu_BIT_1_B		;48
	.word z80cpu_BIT_1_C		;49
	.word z80cpu_BIT_1_D		;4A
	.word z80cpu_BIT_1_E		;4B
	.word z80cpu_BIT_1_H		;4C
	.word z80cpu_BIT_1_L		;4D
	.word z80cpu_BIT_1_IHLI		;4E
	.word z80cpu_BIT_1_A		;4F
	.word z80cpu_BIT_2_B		;50
	.word z80cpu_BIT_2_C		;51
	.word z80cpu_BIT_2_D		;52
	.word z80cpu_BIT_2_E		;53
	.word z80cpu_BIT_2_H		;54
	.word z80cpu_BIT_2_L		;55
	.word z80cpu_BIT_2_IHLI		;56
	.word z80cpu_BIT_2_A		;57
	.word z80cpu_BIT_3_B		;58
	.word z80cpu_BIT_3_C		;59
	.word z80cpu_BIT_3_D		;5A
	.word z80cpu_BIT_3_E		;5B
	.word z80cpu_BIT_3_H		;5C
	.word z80cpu_BIT_3_L		;5D
	.word z80cpu_BIT_3_IHLI		;5E
	.word z80cpu_BIT_3_A		;5F
	.word z80cpu_BIT_4_B		;60
	.word z80cpu_BIT_4_C		;61
	.word z80cpu_BIT_4_D		;62
	.word z80cpu_BIT_4_E		;63
	.word z80cpu_BIT_4_H		;64
	.word z80cpu_BIT_4_L		;65
	.word z80cpu_BIT_4_IHLI		;66
	.word z80cpu_BIT_4_A		;67
	.word z80cpu_BIT_5_B		;68
	.word z80cpu_BIT_5_C		;69
	.word z80cpu_BIT_5_D		;6A
	.word z80cpu_BIT_5_E		;6B
	.word z80cpu_BIT_5_H		;6C
	.word z80cpu_BIT_5_L		;6D
	.word z80cpu_BIT_5_IHLI		;6E
	.word z80cpu_BIT_5_A		;6F
	.word z80cpu_BIT_6_B		;70
	.word z80cpu_BIT_6_C		;71
	.word z80cpu_BIT_6_D		;72
	.word z80cpu_BIT_6_E		;73
	.word z80cpu_BIT_6_H		;74
	.word z80cpu_BIT_6_L		;75
	.word z80cpu_BIT_6_IHLI		;76
	.word z80cpu_BIT_6_A		;77
	.word z80cpu_BIT_7_B		;78
	.word z80cpu_BIT_7_C		;79
	.word z80cpu_BIT_7_D		;7A
	.word z80cpu_BIT_7_E		;7B
	.word z80cpu_BIT_7_H		;7C
	.word z80cpu_BIT_7_L		;7D
	.word z80cpu_BIT_7_IHLI		;7E
	.word z80cpu_BIT_7_A		;7F
	.word z80cpu_RES_0_B		;80
	.word z80cpu_RES_0_C		;81
	.word z80cpu_RES_0_D		;82
	.word z80cpu_RES_0_E		;83
	.word z80cpu_RES_0_H		;84
	.word z80cpu_RES_0_L		;85
	.word z80cpu_RES_0_IHLI		;86
	.word z80cpu_RES_0_A		;87
	.word z80cpu_RES_1_B		;88
	.word z80cpu_RES_1_C		;89
	.word z80cpu_RES_1_D		;8A
	.word z80cpu_RES_1_E		;8B
	.word z80cpu_RES_1_H		;8C
	.word z80cpu_RES_1_L		;8D
	.word z80cpu_RES_1_IHLI		;8E
	.word z80cpu_RES_1_A		;8F
	.word z80cpu_RES_2_B		;90
	.word z80cpu_RES_2_C		;91
	.word z80cpu_RES_2_D		;92
	.word z80cpu_RES_2_E		;93
	.word z80cpu_RES_2_H		;94
	.word z80cpu_RES_2_L		;95
	.word z80cpu_RES_2_IHLI		;96
	.word z80cpu_RES_2_A		;97
	.word z80cpu_RES_3_B		;98
	.word z80cpu_RES_3_C		;99
	.word z80cpu_RES_3_D		;9A
	.word z80cpu_RES_3_E		;9B
	.word z80cpu_RES_3_H		;9C
	.word z80cpu_RES_3_L		;9D
	.word z80cpu_RES_3_IHLI		;9E
	.word z80cpu_RES_3_A		;9F
	.word z80cpu_RES_4_B		;A0
	.word z80cpu_RES_4_C		;A1
	.word z80cpu_RES_4_D		;A2
	.word z80cpu_RES_4_E		;A3
	.word z80cpu_RES_4_H		;A4
	.word z80cpu_RES_4_L		;A5
	.word z80cpu_RES_4_IHLI		;A6
	.word z80cpu_RES_4_A		;A7
	.word z80cpu_RES_5_B		;A8
	.word z80cpu_RES_5_C		;A9
	.word z80cpu_RES_5_D		;AA
	.word z80cpu_RES_5_E		;AB
	.word z80cpu_RES_5_H		;AC
	.word z80cpu_RES_5_L		;AD
	.word z80cpu_RES_5_IHLI		;AE
	.word z80cpu_RES_5_A		;AF
	.word z80cpu_RES_6_B		;B0
	.word z80cpu_RES_6_C		;B1
	.word z80cpu_RES_6_D		;B2
	.word z80cpu_RES_6_E		;B3
	.word z80cpu_RES_6_H		;B4
	.word z80cpu_RES_6_L		;B5
	.word z80cpu_RES_6_IHLI		;B6
	.word z80cpu_RES_6_A		;B7
	.word z80cpu_RES_7_B		;B8
	.word z80cpu_RES_7_C		;B9
	.word z80cpu_RES_7_D		;BA
	.word z80cpu_RES_7_E		;BB
	.word z80cpu_RES_7_H		;BC
	.word z80cpu_RES_7_L		;BD
	.word z80cpu_RES_7_IHLI		;BE
	.word z80cpu_RES_7_A		;BF
	.word z80cpu_SET_0_B		;C0
	.word z80cpu_SET_0_C		;C1
	.word z80cpu_SET_0_D		;C2
	.word z80cpu_SET_0_E		;C3
	.word z80cpu_SET_0_H		;C4
	.word z80cpu_SET_0_L		;C5
	.word z80cpu_SET_0_IHLI		;C6
	.word z80cpu_SET_0_A		;C7
	.word z80cpu_SET_1_B		;C8
	.word z80cpu_SET_1_C		;C9
	.word z80cpu_SET_1_D		;CA
	.word z80cpu_SET_1_E		;CB
	.word z80cpu_SET_1_H		;CC
	.word z80cpu_SET_1_L		;CD
	.word z80cpu_SET_1_IHLI		;CE
	.word z80cpu_SET_1_A		;CF
	.word z80cpu_SET_2_B		;D0
	.word z80cpu_SET_2_C		;D1
	.word z80cpu_SET_2_D		;D2
	.word z80cpu_SET_2_E		;D3
	.word z80cpu_SET_2_H		;D4
	.word z80cpu_SET_2_L		;D5
	.word z80cpu_SET_2_IHLI		;D6
	.word z80cpu_SET_2_A		;D7
	.word z80cpu_SET_3_B		;D8
	.word z80cpu_SET_3_C		;D9
	.word z80cpu_SET_3_D		;DA
	.word z80cpu_SET_3_E		;DB
	.word z80cpu_SET_3_H		;DC
	.word z80cpu_SET_3_L		;DD
	.word z80cpu_SET_3_IHLI		;DE
	.word z80cpu_SET_3_A		;DF
	.word z80cpu_SET_4_B		;E0
	.word z80cpu_SET_4_C		;E1
	.word z80cpu_SET_4_D		;E2
	.word z80cpu_SET_4_E		;E3
	.word z80cpu_SET_4_H		;E4
	.word z80cpu_SET_4_L		;E5
	.word z80cpu_SET_4_IHLI		;E6
	.word z80cpu_SET_4_A		;E7
	.word z80cpu_SET_5_B		;E8
	.word z80cpu_SET_5_C		;E9
	.word z80cpu_SET_5_D		;EA
	.word z80cpu_SET_5_E		;EB
	.word z80cpu_SET_5_H		;EC
	.word z80cpu_SET_5_L		;ED
	.word z80cpu_SET_5_IHLI		;EE
	.word z80cpu_SET_5_A		;EF
	.word z80cpu_SET_6_B		;F0
	.word z80cpu_SET_6_C		;F1
	.word z80cpu_SET_6_D		;F2
	.word z80cpu_SET_6_E		;F3
	.word z80cpu_SET_6_H		;F4
	.word z80cpu_SET_6_L		;F5
	.word z80cpu_SET_6_IHLI		;F6
	.word z80cpu_SET_6_A		;F7
	.word z80cpu_SET_7_B		;F8
	.word z80cpu_SET_7_C		;F9
	.word z80cpu_SET_7_D		;FA
	.word z80cpu_SET_7_E		;FB
	.word z80cpu_SET_7_H		;FC
	.word z80cpu_SET_7_L		;FD
	.word z80cpu_SET_7_IHLI		;FE
	.word z80cpu_SET_7_A		;FF

	.global z80cpu_EDops
z80cpu_EDops:
	.word z80cpu_ERROR		;00
	.word z80cpu_ERROR		;01
	.word z80cpu_ERROR		;02
	.word z80cpu_ERROR		;03
	.word z80cpu_ERROR		;04
	.word z80cpu_ERROR		;05
	.word z80cpu_ERROR		;06
	.word z80cpu_ERROR		;07
	.word z80cpu_ERROR		;08
	.word z80cpu_ERROR		;09
	.word z80cpu_ERROR		;0A
	.word z80cpu_ERROR		;0B
	.word z80cpu_ERROR		;0C
	.word z80cpu_ERROR		;0D
	.word z80cpu_ERROR		;0E
	.word z80cpu_ERROR		;0F
	.word z80cpu_ERROR		;10
	.word z80cpu_ERROR		;11
	.word z80cpu_ERROR		;12
	.word z80cpu_ERROR		;13
	.word z80cpu_ERROR		;14
	.word z80cpu_ERROR		;15
	.word z80cpu_ERROR		;16
	.word z80cpu_ERROR		;17
	.word z80cpu_ERROR		;18
	.word z80cpu_ERROR		;19
	.word z80cpu_ERROR		;1A
	.word z80cpu_ERROR		;1B
	.word z80cpu_ERROR		;1C
	.word z80cpu_ERROR		;1D
	.word z80cpu_ERROR		;1E
	.word z80cpu_ERROR		;1F
	.word z80cpu_ERROR		;20
	.word z80cpu_ERROR		;21
	.word z80cpu_ERROR		;22
	.word z80cpu_ERROR		;23
	.word z80cpu_ERROR		;24
	.word z80cpu_ERROR		;25
	.word z80cpu_ERROR		;26
	.word z80cpu_ERROR		;27
	.word z80cpu_ERROR		;28
	.word z80cpu_ERROR		;29
	.word z80cpu_ERROR		;2A
	.word z80cpu_ERROR		;2B
	.word z80cpu_ERROR		;2C
	.word z80cpu_ERROR		;2D
	.word z80cpu_ERROR		;2E
	.word z80cpu_ERROR		;2F
	.word z80cpu_ERROR		;30
	.word z80cpu_ERROR		;31
	.word z80cpu_ERROR		;32
	.word z80cpu_ERROR		;33
	.word z80cpu_ERROR		;34
	.word z80cpu_ERROR		;35
	.word z80cpu_ERROR		;36
	.word z80cpu_ERROR		;37
	.word z80cpu_ERROR		;38
	.word z80cpu_ERROR		;39
	.word z80cpu_ERROR		;3A
	.word z80cpu_ERROR		;3B
	.word z80cpu_ERROR		;3C
	.word z80cpu_ERROR		;3D
	.word z80cpu_ERROR		;3E
	.word z80cpu_ERROR		;3F
	.word z80cpu_IN_B_ICI		;40
	.word z80cpu_OUT_ICI_B		;41
	.word z80cpu_SBC_HL_BC		;42
	.word z80cpu_LD_IlmI_BC		;43
	.word z80cpu_NEG		;44
	.word z80cpu_RETN		;45
	.word z80cpu_IM_0		;46
	.word z80cpu_LD_I_A		;47
	.word z80cpu_IN_C_ICI		;48
	.word z80cpu_OUT_ICI_C		;49
	.word z80cpu_ADC_HL_BC		;4A
	.word z80cpu_LD_BC_IlmI		;4B
	.word z80cpu_ERROR		;4C
	.word z80cpu_RETI		;4D
	.word z80cpu_ERROR		;4E
	.word z80cpu_LD_R_A		;4F
	.word z80cpu_IN_D_ICI		;50
	.word z80cpu_OUT_ICI_D		;51
	.word z80cpu_SBC_HL_DE		;52
	.word z80cpu_LD_IlmI_DE		;53
	.word z80cpu_ERROR		;54
	.word z80cpu_ERROR		;55
	.word z80cpu_IM_1		;56
	.word z80cpu_LD_A_I		;57
	.word z80cpu_IN_E_ICI		;58
	.word z80cpu_OUT_ICI_E		;59
	.word z80cpu_ADC_HL_DE		;5A
	.word z80cpu_LD_DE_IlmI		;5B
	.word z80cpu_ERROR		;5C
	.word z80cpu_ERROR		;5D
	.word z80cpu_IM_2		;5E
	.word z80cpu_LD_A_R		;5F
	.word z80cpu_IN_H_ICI		;60
	.word z80cpu_OUT_ICI_H		;61
	.word z80cpu_SBC_HL_HL		;62
	.word z80cpu_ERROR		;63
	.word z80cpu_ERROR		;64
	.word z80cpu_ERROR		;65
	.word z80cpu_ERROR		;66
	.word z80cpu_RRD		;67
	.word z80cpu_IN_L_ICI		;68
	.word z80cpu_OUT_ICI_L		;69
	.word z80cpu_ADC_HL_HL		;6A
	.word z80cpu_ERROR		;6B
	.word z80cpu_ERROR		;6C
	.word z80cpu_ERROR		;6D
	.word z80cpu_ERROR		;6E
	.word z80cpu_RLD		;6F
	.word z80cpu_ERROR		;70
	.word z80cpu_ERROR		;71
	.word z80cpu_SBC_HL_SP		;72
	.word z80cpu_LD_IlmI_SP		;73
	.word z80cpu_ERROR		;74
	.word z80cpu_ERROR		;75
	.word z80cpu_ERROR		;76
	.word z80cpu_ERROR		;77
	.word z80cpu_IN_A_ICI		;78
	.word z80cpu_OUT_ICI_A		;79
	.word z80cpu_ADC_HL_SP		;7A
	.word z80cpu_LD_SP_IlmI		;7B
	.word z80cpu_ERROR		;7C
	.word z80cpu_ERROR		;7D
	.word z80cpu_ERROR		;7E
	.word z80cpu_ERROR		;7F
	.word z80cpu_ERROR		;80
	.word z80cpu_ERROR		;81
	.word z80cpu_ERROR		;82
	.word z80cpu_ERROR		;83
	.word z80cpu_ERROR		;84
	.word z80cpu_ERROR		;85
	.word z80cpu_ERROR		;86
	.word z80cpu_ERROR		;87
	.word z80cpu_ERROR		;88
	.word z80cpu_ERROR		;89
	.word z80cpu_ERROR		;8A
	.word z80cpu_ERROR		;8B
	.word z80cpu_ERROR		;8C
	.word z80cpu_ERROR		;8D
	.word z80cpu_ERROR		;8E
	.word z80cpu_ERROR		;8F
	.word z80cpu_ERROR		;90
	.word z80cpu_ERROR		;91
	.word z80cpu_ERROR		;92
	.word z80cpu_ERROR		;93
	.word z80cpu_ERROR		;94
	.word z80cpu_ERROR		;95
	.word z80cpu_ERROR		;96
	.word z80cpu_ERROR		;97
	.word z80cpu_ERROR		;98
	.word z80cpu_ERROR		;99
	.word z80cpu_ERROR		;9A
	.word z80cpu_ERROR		;9B
	.word z80cpu_ERROR		;9C
	.word z80cpu_ERROR		;9D
	.word z80cpu_ERROR		;9E
	.word z80cpu_ERROR		;9F
	.word z80cpu_LDI		;A0
	.word z80cpu_CPI		;A1
	.word z80cpu_INI		;A2
	.word z80cpu_OUTI		;A3
	.word z80cpu_ERROR		;A4
	.word z80cpu_ERROR		;A5
	.word z80cpu_ERROR		;A6
	.word z80cpu_ERROR		;A7
	.word z80cpu_LDD		;A8
	.word z80cpu_CPD		;A9
	.word z80cpu_IND		;AA
	.word z80cpu_OUTD		;AB
	.word z80cpu_ERROR		;AC
	.word z80cpu_ERROR		;AD
	.word z80cpu_ERROR		;AE
	.word z80cpu_ERROR		;AF
	.word z80cpu_LDIR		;B0
	.word z80cpu_CPIR		;B1
	.word z80cpu_INIR		;B2
	.word z80cpu_OTIR		;B3
	.word z80cpu_ERROR		;B4
	.word z80cpu_ERROR		;B5
	.word z80cpu_ERROR		;B6
	.word z80cpu_ERROR		;B7
	.word z80cpu_LDDR		;B8
	.word z80cpu_CPDR		;B9
	.word z80cpu_INDR		;BA
	.word z80cpu_OTDR		;BB
	.word z80cpu_ERROR		;BC
	.word z80cpu_ERROR		;BD
	.word z80cpu_ERROR		;BE
	.word z80cpu_ERROR		;BF
	.word z80cpu_ERROR		;C0
	.word z80cpu_ERROR		;C1
	.word z80cpu_ERROR		;C2
	.word z80cpu_ERROR		;C3
	.word z80cpu_ERROR		;C4
	.word z80cpu_ERROR		;C5
	.word z80cpu_ERROR		;C6
	.word z80cpu_ERROR		;C7
	.word z80cpu_ERROR		;C8
	.word z80cpu_ERROR		;C9
	.word z80cpu_ERROR		;CA
	.word z80cpu_ERROR		;CB
	.word z80cpu_ERROR		;CC
	.word z80cpu_ERROR		;CD
	.word z80cpu_ERROR		;CE
	.word z80cpu_ERROR		;CF
	.word z80cpu_ERROR		;D0
	.word z80cpu_ERROR		;D1
	.word z80cpu_ERROR		;D2
	.word z80cpu_ERROR		;D3
	.word z80cpu_ERROR		;D4
	.word z80cpu_ERROR		;D5
	.word z80cpu_ERROR		;D6
	.word z80cpu_ERROR		;D7
	.word z80cpu_ERROR		;D8
	.word z80cpu_ERROR		;D9
	.word z80cpu_ERROR		;DA
	.word z80cpu_ERROR		;DB
	.word z80cpu_ERROR		;DC
	.word z80cpu_ERROR		;DD
	.word z80cpu_ERROR		;DE
	.word z80cpu_ERROR		;DF
	.word z80cpu_ERROR		;E0
	.word z80cpu_ERROR		;E1
	.word z80cpu_ERROR		;E2
	.word z80cpu_ERROR		;E3
	.word z80cpu_ERROR		;E4
	.word z80cpu_ERROR		;E5
	.word z80cpu_ERROR		;E6
	.word z80cpu_ERROR		;E7
	.word z80cpu_ERROR		;E8
	.word z80cpu_ERROR		;E9
	.word z80cpu_ERROR		;EA
	.word z80cpu_ERROR		;EB
	.word z80cpu_ERROR		;EC
	.word z80cpu_ERROR		;ED
	.word z80cpu_ERROR		;EE
	.word z80cpu_ERROR		;EF
	.word z80cpu_ERROR		;F0
	.word z80cpu_ERROR		;F1
	.word z80cpu_ERROR		;F2
	.word z80cpu_ERROR		;F3
	.word z80cpu_ERROR		;F4
	.word z80cpu_ERROR		;F5
	.word z80cpu_ERROR		;F6
	.word z80cpu_ERROR		;F7
	.word z80cpu_ERROR		;F8
	.word z80cpu_ERROR		;F9
	.word z80cpu_ERROR		;FA
	.word z80cpu_ERROR		;FB
	.word z80cpu_ERROR		;FC
	.word z80cpu_ERROR		;FD
	.word z80cpu_ERROR		;FE
	.word z80cpu_ERROR		;FF

	.global z80cpu_DDops
z80cpu_DDops:
	.word z80cpu_ERROR		;00
	.word z80cpu_ERROR		;01
	.word z80cpu_ERROR		;02
	.word z80cpu_ERROR		;03
	.word z80cpu_ERROR		;04
	.word z80cpu_ERROR		;05
	.word z80cpu_ERROR		;06
	.word z80cpu_ERROR		;07
	.word z80cpu_ERROR		;08
	.word z80cpu_ADD_IX_BC		;09
	.word z80cpu_ERROR		;0A
	.word z80cpu_ERROR		;0B
	.word z80cpu_ERROR		;0C
	.word z80cpu_ERROR		;0D
	.word z80cpu_ERROR		;0E
	.word z80cpu_ERROR		;0F
	.word z80cpu_ERROR		;10
	.word z80cpu_ERROR		;11
	.word z80cpu_ERROR		;12
	.word z80cpu_ERROR		;13
	.word z80cpu_ERROR		;14
	.word z80cpu_ERROR		;15
	.word z80cpu_ERROR		;16
	.word z80cpu_ERROR		;17
	.word z80cpu_ERROR		;18
	.word z80cpu_ADD_IX_DE		;19
	.word z80cpu_ERROR		;1A
	.word z80cpu_ERROR		;1B
	.word z80cpu_ERROR		;1C
	.word z80cpu_ERROR		;1D
	.word z80cpu_ERROR		;1E
	.word z80cpu_ERROR		;1F
	.word z80cpu_ERROR		;20
	.word z80cpu_LD_IX_lm		;21
	.word z80cpu_LD_IlmI_IX		;22
	.word z80cpu_INC_IX		;23
	.word z80cpu_INC_IXH		;24
	.word z80cpu_DEC_IXH		;25
	.word z80cpu_LD_IXH_n		;26
	.word z80cpu_ERROR		;27
	.word z80cpu_ERROR		;28
	.word z80cpu_ADD_IX_IX		;29
	.word z80cpu_LD_IX_IlmI		;2A
	.word z80cpu_DEC_IX		;2B
	.word z80cpu_INC_IXL		;2C
	.word z80cpu_DEC_IXL		;2D
	.word z80cpu_LD_IXL_n		;2E
	.word z80cpu_ERROR		;2F
	.word z80cpu_ERROR		;30
	.word z80cpu_ERROR		;31
	.word z80cpu_ERROR		;32
	.word z80cpu_ERROR		;33
	.word z80cpu_INC_IIX_dI		;34
	.word z80cpu_DEC_IIX_dI		;35
	.word z80cpu_LD_IIX_dI_n	;36
	.word z80cpu_ERROR		;37
	.word z80cpu_ERROR		;38
	.word z80cpu_ADD_IX_SP		;39
	.word z80cpu_ERROR		;3A
	.word z80cpu_ERROR		;3B
	.word z80cpu_ERROR		;3C
	.word z80cpu_ERROR		;3D
	.word z80cpu_ERROR		;3E
	.word z80cpu_ERROR		;3F
	.word z80cpu_ERROR		;40
	.word z80cpu_ERROR		;41
	.word z80cpu_ERROR		;42
	.word z80cpu_ERROR		;43
	.word z80cpu_LD_B_IXH		;44
	.word z80cpu_LD_B_IXL		;45
	.word z80cpu_LD_B_IIX_dI	;46
	.word z80cpu_ERROR		;47
	.word z80cpu_ERROR		;48
	.word z80cpu_ERROR		;49
	.word z80cpu_ERROR		;4A
	.word z80cpu_ERROR		;4B
	.word z80cpu_LD_C_IXH		;4C
	.word z80cpu_LD_C_IXL		;4D
	.word z80cpu_LD_C_IIX_dI	;4E
	.word z80cpu_ERROR		;4F
	.word z80cpu_ERROR		;50
	.word z80cpu_ERROR		;51
	.word z80cpu_ERROR		;52
	.word z80cpu_ERROR		;53
	.word z80cpu_LD_D_IXH		;54
	.word z80cpu_LD_D_IXL		;55
	.word z80cpu_LD_D_IIX_dI	;56
	.word z80cpu_ERROR		;57
	.word z80cpu_ERROR		;58
	.word z80cpu_ERROR		;59
	.word z80cpu_ERROR		;5A
	.word z80cpu_ERROR		;5B
	.word z80cpu_LD_E_IXH		;5C
	.word z80cpu_LD_E_IXL		;5D
	.word z80cpu_LD_E_IIX_dI	;5E
	.word z80cpu_ERROR		;5F
	.word z80cpu_LD_IXH_B		;60
	.word z80cpu_LD_IXH_C		;61
	.word z80cpu_LD_IXH_D		;62
	.word z80cpu_LD_IXH_E		;63
	.word z80cpu_LD_IXH_IXH		;64
	.word z80cpu_LD_IXH_IXL		;65
	.word z80cpu_LD_H_IIX_dI	;66
	.word z80cpu_LD_IXH_A		;67
	.word z80cpu_LD_IXL_B		;68
	.word z80cpu_LD_IXL_C		;69
	.word z80cpu_LD_IXL_D		;6A
	.word z80cpu_LD_IXL_E		;6B
	.word z80cpu_LD_IXL_IXH		;6C
	.word z80cpu_LD_IXL_IXL		;6D
	.word z80cpu_LD_L_IIX_dI	;6E
	.word z80cpu_LD_IXL_A		;6F
	.word z80cpu_LD_IIX_dI_B	;70
	.word z80cpu_LD_IIX_dI_C	;71
	.word z80cpu_LD_IIX_dI_D	;72
	.word z80cpu_LD_IIX_dI_E	;73
	.word z80cpu_LD_IIX_dI_H	;74
	.word z80cpu_LD_IIX_dI_L	;75
	.word z80cpu_ERROR		;76
	.word z80cpu_LD_IIX_dI_A	;77
	.word z80cpu_ERROR		;78
	.word z80cpu_ERROR		;79
	.word z80cpu_ERROR		;7A
	.word z80cpu_ERROR		;7B
	.word z80cpu_LD_A_IXH		;7C
	.word z80cpu_LD_A_IXL		;7D
	.word z80cpu_LD_A_IIX_dI	;7E
	.word z80cpu_ERROR		;7F
	.word z80cpu_ERROR		;80
	.word z80cpu_ERROR		;81
	.word z80cpu_ERROR		;82
	.word z80cpu_ERROR		;83
	.word z80cpu_ADD_A_IXH		;84
	.word z80cpu_ADD_A_IXL		;85
	.word z80cpu_ADD_A_IIX_dI	;86
	.word z80cpu_ERROR		;87
	.word z80cpu_ERROR		;88
	.word z80cpu_ERROR		;89
	.word z80cpu_ERROR		;8A
	.word z80cpu_ERROR		;8B
	.word z80cpu_ADC_A_IXH		;8C
	.word z80cpu_ADC_A_IXL		;8D
	.word z80cpu_ADC_A_IIX_dI	;8E
	.word z80cpu_ERROR		;8F
	.word z80cpu_ERROR		;90
	.word z80cpu_ERROR		;91
	.word z80cpu_ERROR		;92
	.word z80cpu_ERROR		;93
	.word z80cpu_SUB_IXH		;94
	.word z80cpu_SUB_IXL		;95
	.word z80cpu_SUB_IIX_dI		;96
	.word z80cpu_ERROR		;97
	.word z80cpu_ERROR		;98
	.word z80cpu_ERROR		;99
	.word z80cpu_ERROR		;9A
	.word z80cpu_ERROR		;9B
	.word z80cpu_SBC_A_IXH		;9C
	.word z80cpu_SBC_A_IXL		;9D
	.word z80cpu_SBC_A_IIX_dI	;9E
	.word z80cpu_ERROR		;9F
	.word z80cpu_ERROR		;A0
	.word z80cpu_ERROR		;A1
	.word z80cpu_ERROR		;A2
	.word z80cpu_ERROR		;A3
	.word z80cpu_AND_IXH		;A4
	.word z80cpu_AND_IXL		;A5
	.word z80cpu_AND_IIX_dI		;A6
	.word z80cpu_ERROR		;A7
	.word z80cpu_ERROR		;A8
	.word z80cpu_ERROR		;A9
	.word z80cpu_ERROR		;AA
	.word z80cpu_ERROR		;AB
	.word z80cpu_XOR_IXH		;AC
	.word z80cpu_XOR_IXL		;AD
	.word z80cpu_XOR_IIX_dI		;AE
	.word z80cpu_ERROR		;AF
	.word z80cpu_ERROR		;B0
	.word z80cpu_ERROR		;B1
	.word z80cpu_ERROR		;B2
	.word z80cpu_ERROR		;B3
	.word z80cpu_OR_IXH		;B4
	.word z80cpu_OR_IXL		;B5
	.word z80cpu_OR_IIX_dI		;B6
	.word z80cpu_ERROR		;B7
	.word z80cpu_ERROR		;B8
	.word z80cpu_ERROR		;B9
	.word z80cpu_ERROR		;BA
	.word z80cpu_ERROR		;BB
	.word z80cpu_CP_IXH		;BC
	.word z80cpu_CP_IXL		;BD
	.word z80cpu_CP_IIX_dI		;BE
	.word z80cpu_ERROR		;BF
	.word z80cpu_ERROR		;C0
	.word z80cpu_ERROR		;C1
	.word z80cpu_ERROR		;C2
	.word z80cpu_ERROR		;C3
	.word z80cpu_ERROR		;C4
	.word z80cpu_ERROR		;C5
	.word z80cpu_ERROR		;C6
	.word z80cpu_ERROR		;C7
	.word z80cpu_ERROR		;C8
	.word z80cpu_ERROR		;C9
	.word z80cpu_ERROR		;CA
	.word z80cpu_DDCB		;CB
	.word z80cpu_ERROR		;CC
	.word z80cpu_ERROR		;CD
	.word z80cpu_ERROR		;CE
	.word z80cpu_ERROR		;CF
	.word z80cpu_ERROR		;D0
	.word z80cpu_ERROR		;D1
	.word z80cpu_ERROR		;D2
	.word z80cpu_ERROR		;D3
	.word z80cpu_ERROR		;D4
	.word z80cpu_ERROR		;D5
	.word z80cpu_ERROR		;D6
	.word z80cpu_ERROR		;D7
	.word z80cpu_ERROR		;D8
	.word z80cpu_ERROR		;D9
	.word z80cpu_ERROR		;DA
	.word z80cpu_ERROR		;DB
	.word z80cpu_ERROR		;DC
	.word z80cpu_ERROR		;DD
	.word z80cpu_ERROR		;DE
	.word z80cpu_ERROR		;DF
	.word z80cpu_ERROR		;E0
	.word z80cpu_POP_IX		;E1
	.word z80cpu_ERROR		;E2
	.word z80cpu_EX_ISPI_IX		;E3
	.word z80cpu_ERROR		;E4
	.word z80cpu_PUSH_IX		;E5
	.word z80cpu_ERROR		;E6
	.word z80cpu_ERROR		;E7
	.word z80cpu_ERROR		;E8
	.word z80cpu_JP_IIXI		;E9
	.word z80cpu_ERROR		;EA
	.word z80cpu_ERROR		;EB
	.word z80cpu_ERROR		;EC
	.word z80cpu_ERROR		;ED
	.word z80cpu_ERROR		;EE
	.word z80cpu_ERROR		;EF
	.word z80cpu_ERROR		;F0
	.word z80cpu_ERROR		;F1
	.word z80cpu_ERROR		;F2
	.word z80cpu_ERROR		;F3
	.word z80cpu_ERROR		;F4
	.word z80cpu_ERROR		;F5
	.word z80cpu_ERROR		;F6
	.word z80cpu_ERROR		;F7
	.word z80cpu_ERROR		;F8
	.word z80cpu_LD_SP_IX		;F9
	.word z80cpu_ERROR		;FA
	.word z80cpu_ERROR		;FB
	.word z80cpu_ERROR		;FC
	.word z80cpu_ERROR		;FD
	.word z80cpu_ERROR		;FE
	.word z80cpu_ERROR		;FF

	.global z80cpu_FDops
z80cpu_FDops:
	.word z80cpu_ERROR		;00
	.word z80cpu_ERROR		;01
	.word z80cpu_ERROR		;02
	.word z80cpu_ERROR		;03
	.word z80cpu_ERROR		;04
	.word z80cpu_ERROR		;05
	.word z80cpu_ERROR		;06
	.word z80cpu_ERROR		;07
	.word z80cpu_ERROR		;08
	.word z80cpu_ADD_IY_BC		;09
	.word z80cpu_ERROR		;0A
	.word z80cpu_ERROR		;0B
	.word z80cpu_ERROR		;0C
	.word z80cpu_ERROR		;0D
	.word z80cpu_ERROR		;0E
	.word z80cpu_ERROR		;0F
	.word z80cpu_ERROR		;10
	.word z80cpu_ERROR		;11
	.word z80cpu_ERROR		;12
	.word z80cpu_ERROR		;13
	.word z80cpu_ERROR		;14
	.word z80cpu_ERROR		;15
	.word z80cpu_ERROR		;16
	.word z80cpu_ERROR		;17
	.word z80cpu_ERROR		;18
	.word z80cpu_ADD_IY_DE		;19
	.word z80cpu_ERROR		;1A
	.word z80cpu_ERROR		;1B
	.word z80cpu_ERROR		;1C
	.word z80cpu_ERROR		;1D
	.word z80cpu_ERROR		;1E
	.word z80cpu_ERROR		;1F
	.word z80cpu_ERROR		;20
	.word z80cpu_LD_IY_lm		;21
	.word z80cpu_LD_IlmI_IY		;22
	.word z80cpu_INC_IY		;23
	.word z80cpu_INC_IYH		;24
	.word z80cpu_DEC_IYH		;25
	.word z80cpu_LD_IYH_n		;26
	.word z80cpu_ERROR		;27
	.word z80cpu_ERROR		;28
	.word z80cpu_ADD_IY_IY		;29
	.word z80cpu_LD_IY_IlmI		;2A
	.word z80cpu_DEC_IY		;2B
	.word z80cpu_INC_IYL		;2C
	.word z80cpu_DEC_IYL		;2D
	.word z80cpu_LD_IYL_n		;2E
	.word z80cpu_ERROR		;2F
	.word z80cpu_ERROR		;30
	.word z80cpu_ERROR		;31
	.word z80cpu_ERROR		;32
	.word z80cpu_ERROR		;33
	.word z80cpu_INC_IIY_dI		;34
	.word z80cpu_DEC_IIY_dI		;35
	.word z80cpu_LD_IIY_dI_n	;36
	.word z80cpu_ERROR		;37
	.word z80cpu_ERROR		;38
	.word z80cpu_ADD_IY_SP		;39
	.word z80cpu_ERROR		;3A
	.word z80cpu_ERROR		;3B
	.word z80cpu_ERROR		;3C
	.word z80cpu_ERROR		;3D
	.word z80cpu_ERROR		;3E
	.word z80cpu_ERROR		;3F
	.word z80cpu_ERROR		;40
	.word z80cpu_ERROR		;41
	.word z80cpu_ERROR		;42
	.word z80cpu_ERROR		;43
	.word z80cpu_LD_B_IYH		;44
	.word z80cpu_LD_B_IYL		;45
	.word z80cpu_LD_B_IIY_dI	;46
	.word z80cpu_ERROR		;47
	.word z80cpu_ERROR		;48
	.word z80cpu_ERROR		;49
	.word z80cpu_ERROR		;4A
	.word z80cpu_ERROR		;4B
	.word z80cpu_LD_C_IYH		;4C
	.word z80cpu_LD_C_IYL		;4D
	.word z80cpu_LD_C_IIY_dI	;4E
	.word z80cpu_ERROR		;4F
	.word z80cpu_ERROR		;50
	.word z80cpu_ERROR		;51
	.word z80cpu_ERROR		;52
	.word z80cpu_ERROR		;53
	.word z80cpu_LD_D_IYH		;54
	.word z80cpu_LD_D_IYL		;55
	.word z80cpu_LD_D_IIY_dI	;56
	.word z80cpu_ERROR		;57
	.word z80cpu_ERROR		;58
	.word z80cpu_ERROR		;59
	.word z80cpu_ERROR		;5A
	.word z80cpu_ERROR		;5B
	.word z80cpu_LD_E_IYH		;5C
	.word z80cpu_LD_E_IYL		;5D
	.word z80cpu_LD_E_IIY_dI	;5E
	.word z80cpu_ERROR		;5F
	.word z80cpu_LD_IYH_B		;60
	.word z80cpu_LD_IYH_C		;61
	.word z80cpu_LD_IYH_D		;62
	.word z80cpu_LD_IYH_E		;63
	.word z80cpu_LD_IYH_IYH		;64
	.word z80cpu_LD_IYH_IYL		;65
	.word z80cpu_LD_H_IIY_dI	;66
	.word z80cpu_LD_IYH_A		;67
	.word z80cpu_LD_IYL_B		;68
	.word z80cpu_LD_IYL_C		;69
	.word z80cpu_LD_IYL_D		;6A
	.word z80cpu_LD_IYL_E		;6B
	.word z80cpu_LD_IYL_IYH		;6C
	.word z80cpu_LD_IYL_IYL		;6D
	.word z80cpu_LD_L_IIY_dI	;6E
	.word z80cpu_LD_IYL_A		;6F
	.word z80cpu_LD_IIY_dI_B	;70
	.word z80cpu_LD_IIY_dI_C	;71
	.word z80cpu_LD_IIY_dI_D	;72
	.word z80cpu_LD_IIY_dI_E	;73
	.word z80cpu_LD_IIY_dI_H	;74
	.word z80cpu_LD_IIY_dI_L	;75
	.word z80cpu_ERROR		;76
	.word z80cpu_LD_IIY_dI_A	;77
	.word z80cpu_ERROR		;78
	.word z80cpu_ERROR		;79
	.word z80cpu_ERROR		;7A
	.word z80cpu_ERROR		;7B
	.word z80cpu_LD_A_IYH		;7C
	.word z80cpu_LD_A_IYL		;7D
	.word z80cpu_LD_A_IIY_dI	;7E
	.word z80cpu_ERROR		;7F
	.word z80cpu_ERROR		;80
	.word z80cpu_ERROR		;81
	.word z80cpu_ERROR		;82
	.word z80cpu_ERROR		;83
	.word z80cpu_ADD_A_IYH		;84
	.word z80cpu_ADD_A_IYL		;85
	.word z80cpu_ADD_A_IIY_dI	;86
	.word z80cpu_ERROR		;87
	.word z80cpu_ERROR		;88
	.word z80cpu_ERROR		;89
	.word z80cpu_ERROR		;8A
	.word z80cpu_ERROR		;8B
	.word z80cpu_ADC_A_IYH		;8C
	.word z80cpu_ADC_A_IYL		;8D
	.word z80cpu_ADC_A_IIY_dI	;8E
	.word z80cpu_ERROR		;8F
	.word z80cpu_ERROR		;90
	.word z80cpu_ERROR		;91
	.word z80cpu_ERROR		;92
	.word z80cpu_ERROR		;93
	.word z80cpu_SUB_IYH		;94
	.word z80cpu_SUB_IYL		;95
	.word z80cpu_SUB_IIY_dI		;96
	.word z80cpu_ERROR		;97
	.word z80cpu_ERROR		;98
	.word z80cpu_ERROR		;99
	.word z80cpu_ERROR		;9A
	.word z80cpu_ERROR		;9B
	.word z80cpu_SBC_A_IYH		;9C
	.word z80cpu_SBC_A_IYL		;9D
	.word z80cpu_SBC_A_IIY_dI	;9E
	.word z80cpu_ERROR		;9F
	.word z80cpu_ERROR		;A0
	.word z80cpu_ERROR		;A1
	.word z80cpu_ERROR		;A2
	.word z80cpu_ERROR		;A3
	.word z80cpu_AND_IYH		;A4
	.word z80cpu_AND_IYL		;A5
	.word z80cpu_AND_IIY_dI		;A6
	.word z80cpu_ERROR		;A7
	.word z80cpu_ERROR		;A8
	.word z80cpu_ERROR		;A9
	.word z80cpu_ERROR		;AA
	.word z80cpu_ERROR		;AB
	.word z80cpu_XOR_IYH		;AC
	.word z80cpu_XOR_IYL		;AD
	.word z80cpu_XOR_IIY_dI		;AE
	.word z80cpu_ERROR		;AF
	.word z80cpu_ERROR		;B0
	.word z80cpu_ERROR		;B1
	.word z80cpu_ERROR		;B2
	.word z80cpu_ERROR		;B3
	.word z80cpu_OR_IYH		;B4
	.word z80cpu_OR_IYL		;B5
	.word z80cpu_OR_IIY_dI		;B6
	.word z80cpu_ERROR		;B7
	.word z80cpu_ERROR		;B8
	.word z80cpu_ERROR		;B9
	.word z80cpu_ERROR		;BA
	.word z80cpu_ERROR		;BB
	.word z80cpu_CP_IYH		;BC
	.word z80cpu_CP_IYL		;BD
	.word z80cpu_CP_IIY_dI		;BE
	.word z80cpu_ERROR		;BF
	.word z80cpu_ERROR		;C0
	.word z80cpu_ERROR		;C1
	.word z80cpu_ERROR		;C2
	.word z80cpu_ERROR		;C3
	.word z80cpu_ERROR		;C4
	.word z80cpu_ERROR		;C5
	.word z80cpu_ERROR		;C6
	.word z80cpu_ERROR		;C7
	.word z80cpu_ERROR		;C8
	.word z80cpu_ERROR		;C9
	.word z80cpu_ERROR		;CA
	.word z80cpu_FDCB		;CB
	.word z80cpu_ERROR		;CC
	.word z80cpu_ERROR		;CD
	.word z80cpu_ERROR		;CE
	.word z80cpu_ERROR		;CF
	.word z80cpu_ERROR		;D0
	.word z80cpu_ERROR		;D1
	.word z80cpu_ERROR		;D2
	.word z80cpu_ERROR		;D3
	.word z80cpu_ERROR		;D4
	.word z80cpu_ERROR		;D5
	.word z80cpu_ERROR		;D6
	.word z80cpu_ERROR		;D7
	.word z80cpu_ERROR		;D8
	.word z80cpu_ERROR		;D9
	.word z80cpu_ERROR		;DA
	.word z80cpu_ERROR		;DB
	.word z80cpu_ERROR		;DC
	.word z80cpu_ERROR		;DD
	.word z80cpu_ERROR		;DE
	.word z80cpu_ERROR		;DF
	.word z80cpu_ERROR		;E0
	.word z80cpu_POP_IY		;E1
	.word z80cpu_ERROR		;E2
	.word z80cpu_EX_ISPI_IY		;E3
	.word z80cpu_ERROR		;E4
	.word z80cpu_PUSH_IY		;E5
	.word z80cpu_ERROR		;E6
	.word z80cpu_ERROR		;E7
	.word z80cpu_ERROR		;E8
	.word z80cpu_JP_IIYI		;E9
	.word z80cpu_ERROR		;EA
	.word z80cpu_ERROR		;EB
	.word z80cpu_ERROR		;EC
	.word z80cpu_ERROR		;ED
	.word z80cpu_ERROR		;EE
	.word z80cpu_ERROR		;EF
	.word z80cpu_ERROR		;F0
	.word z80cpu_ERROR		;F1
	.word z80cpu_ERROR		;F2
	.word z80cpu_ERROR		;F3
	.word z80cpu_ERROR		;F4
	.word z80cpu_ERROR		;F5
	.word z80cpu_ERROR		;F6
	.word z80cpu_ERROR		;F7
	.word z80cpu_ERROR		;F8
	.word z80cpu_LD_SP_IY		;F9
	.word z80cpu_ERROR		;FA
	.word z80cpu_ERROR		;FB
	.word z80cpu_ERROR		;FC
	.word z80cpu_ERROR		;FD
	.word z80cpu_ERROR		;FE
	.word z80cpu_ERROR		;FF

	.global z80cpu_XXCBops
z80cpu_XXCBops:
	.word z80cpu_ERROR		;00
	.word z80cpu_ERROR		;01
	.word z80cpu_ERROR		;02
	.word z80cpu_ERROR		;03
	.word z80cpu_ERROR		;04
	.word z80cpu_ERROR		;05
	.word z80cpu_RLC_IaddrI		;06
	.word z80cpu_ERROR		;07
	.word z80cpu_ERROR		;08
	.word z80cpu_ERROR		;09
	.word z80cpu_ERROR		;0A
	.word z80cpu_ERROR		;0B
	.word z80cpu_ERROR		;0C
	.word z80cpu_ERROR		;0D
	.word z80cpu_RRC_IaddrI		;0E
	.word z80cpu_ERROR		;0F
	.word z80cpu_ERROR		;10
	.word z80cpu_ERROR		;11
	.word z80cpu_ERROR		;12
	.word z80cpu_ERROR		;13
	.word z80cpu_ERROR		;14
	.word z80cpu_ERROR		;15
	.word z80cpu_RL_IaddrI		;16
	.word z80cpu_ERROR		;17
	.word z80cpu_ERROR		;18
	.word z80cpu_ERROR		;19
	.word z80cpu_ERROR		;1A
	.word z80cpu_ERROR		;1B
	.word z80cpu_ERROR		;1C
	.word z80cpu_ERROR		;1D
	.word z80cpu_RR_IaddrI		;1E
	.word z80cpu_ERROR		;1F
	.word z80cpu_ERROR		;20
	.word z80cpu_ERROR		;21
	.word z80cpu_ERROR		;22
	.word z80cpu_ERROR		;23
	.word z80cpu_ERROR		;24
	.word z80cpu_ERROR		;25
	.word z80cpu_SLA_IaddrI		;26
	.word z80cpu_ERROR		;27
	.word z80cpu_ERROR		;28
	.word z80cpu_ERROR		;29
	.word z80cpu_ERROR		;2A
	.word z80cpu_ERROR		;2B
	.word z80cpu_ERROR		;2C
	.word z80cpu_ERROR		;2D
	.word z80cpu_SRA_IaddrI		;2E
	.word z80cpu_ERROR		;2F
	.word z80cpu_ERROR		;30
	.word z80cpu_ERROR		;31
	.word z80cpu_ERROR		;32
	.word z80cpu_ERROR		;33
	.word z80cpu_ERROR		;34
	.word z80cpu_ERROR		;35
	.word z80cpu_ERROR		;36
	.word z80cpu_ERROR		;37
	.word z80cpu_ERROR		;38
	.word z80cpu_ERROR		;39
	.word z80cpu_ERROR		;3A
	.word z80cpu_ERROR		;3B
	.word z80cpu_ERROR		;3C
	.word z80cpu_ERROR		;3D
	.word z80cpu_SRL_IaddrI		;3E
	.word z80cpu_ERROR		;3F
	.word z80cpu_ERROR		;40
	.word z80cpu_ERROR		;41
	.word z80cpu_ERROR		;42
	.word z80cpu_ERROR		;43
	.word z80cpu_ERROR		;44
	.word z80cpu_ERROR		;45
	.word z80cpu_BIT_0_IaddrI	;46
	.word z80cpu_ERROR		;47
	.word z80cpu_ERROR		;48
	.word z80cpu_ERROR		;49
	.word z80cpu_ERROR		;4A
	.word z80cpu_ERROR		;4B
	.word z80cpu_ERROR		;4C
	.word z80cpu_ERROR		;4D
	.word z80cpu_BIT_1_IaddrI	;4E
	.word z80cpu_ERROR		;4F
	.word z80cpu_ERROR		;50
	.word z80cpu_ERROR		;51
	.word z80cpu_ERROR		;52
	.word z80cpu_ERROR		;53
	.word z80cpu_ERROR		;54
	.word z80cpu_ERROR		;55
	.word z80cpu_BIT_2_IaddrI	;56
	.word z80cpu_ERROR		;57
	.word z80cpu_ERROR		;58
	.word z80cpu_ERROR		;59
	.word z80cpu_ERROR		;5A
	.word z80cpu_ERROR		;5B
	.word z80cpu_ERROR		;5C
	.word z80cpu_ERROR		;5D
	.word z80cpu_BIT_3_IaddrI	;5E
	.word z80cpu_ERROR		;5F
	.word z80cpu_ERROR		;60
	.word z80cpu_ERROR		;61
	.word z80cpu_ERROR		;62
	.word z80cpu_ERROR		;63
	.word z80cpu_ERROR		;64
	.word z80cpu_ERROR		;65
	.word z80cpu_BIT_4_IaddrI	;66
	.word z80cpu_ERROR		;67
	.word z80cpu_ERROR		;68
	.word z80cpu_ERROR		;69
	.word z80cpu_ERROR		;6A
	.word z80cpu_ERROR		;6B
	.word z80cpu_ERROR		;6C
	.word z80cpu_ERROR		;6D
	.word z80cpu_BIT_5_IaddrI	;6E
	.word z80cpu_ERROR		;6F
	.word z80cpu_ERROR		;70
	.word z80cpu_ERROR		;71
	.word z80cpu_ERROR		;72
	.word z80cpu_ERROR		;73
	.word z80cpu_ERROR		;74
	.word z80cpu_ERROR		;75
	.word z80cpu_BIT_6_IaddrI	;76
	.word z80cpu_ERROR		;77
	.word z80cpu_ERROR		;78
	.word z80cpu_ERROR		;79
	.word z80cpu_ERROR		;7A
	.word z80cpu_ERROR		;7B
	.word z80cpu_ERROR		;7C
	.word z80cpu_ERROR		;7D
	.word z80cpu_BIT_7_IaddrI	;7E
	.word z80cpu_ERROR		;7F
	.word z80cpu_ERROR		;80
	.word z80cpu_ERROR		;81
	.word z80cpu_ERROR		;82
	.word z80cpu_ERROR		;83
	.word z80cpu_ERROR		;84
	.word z80cpu_ERROR		;85
	.word z80cpu_RES_0_IaddrI	;86
	.word z80cpu_ERROR		;87
	.word z80cpu_ERROR		;88
	.word z80cpu_ERROR		;89
	.word z80cpu_ERROR		;8A
	.word z80cpu_ERROR		;8B
	.word z80cpu_ERROR		;8C
	.word z80cpu_ERROR		;8D
	.word z80cpu_RES_1_IaddrI	;8E
	.word z80cpu_ERROR		;8F
	.word z80cpu_ERROR		;90
	.word z80cpu_ERROR		;91
	.word z80cpu_ERROR		;92
	.word z80cpu_ERROR		;93
	.word z80cpu_ERROR		;94
	.word z80cpu_ERROR		;95
	.word z80cpu_RES_2_IaddrI	;96
	.word z80cpu_ERROR		;97
	.word z80cpu_ERROR		;98
	.word z80cpu_ERROR		;99
	.word z80cpu_ERROR		;9A
	.word z80cpu_ERROR		;9B
	.word z80cpu_ERROR		;9C
	.word z80cpu_ERROR		;9D
	.word z80cpu_RES_3_IaddrI	;9E
	.word z80cpu_ERROR		;9F
	.word z80cpu_ERROR		;A0
	.word z80cpu_ERROR		;A1
	.word z80cpu_ERROR		;A2
	.word z80cpu_ERROR		;A3
	.word z80cpu_ERROR		;A4
	.word z80cpu_ERROR		;A5
	.word z80cpu_RES_4_IaddrI	;A6
	.word z80cpu_ERROR		;A7
	.word z80cpu_ERROR		;A8
	.word z80cpu_ERROR		;A9
	.word z80cpu_ERROR		;AA
	.word z80cpu_ERROR		;AB
	.word z80cpu_ERROR		;AC
	.word z80cpu_ERROR		;AD
	.word z80cpu_RES_5_IaddrI	;AE
	.word z80cpu_ERROR		;AF
	.word z80cpu_ERROR		;B0
	.word z80cpu_ERROR		;B1
	.word z80cpu_ERROR		;B2
	.word z80cpu_ERROR		;B3
	.word z80cpu_ERROR		;B4
	.word z80cpu_ERROR		;B5
	.word z80cpu_RES_6_IaddrI	;B6
	.word z80cpu_ERROR		;B7
	.word z80cpu_ERROR		;B8
	.word z80cpu_ERROR		;B9
	.word z80cpu_ERROR		;BA
	.word z80cpu_ERROR		;BB
	.word z80cpu_ERROR		;BC
	.word z80cpu_ERROR		;BD
	.word z80cpu_RES_7_IaddrI	;BE
	.word z80cpu_ERROR		;BF
	.word z80cpu_ERROR		;C0
	.word z80cpu_ERROR		;C1
	.word z80cpu_ERROR		;C2
	.word z80cpu_ERROR		;C3
	.word z80cpu_ERROR		;C4
	.word z80cpu_ERROR		;C5
	.word z80cpu_SET_0_IaddrI	;C6
	.word z80cpu_ERROR		;C7
	.word z80cpu_ERROR		;C8
	.word z80cpu_ERROR		;C9
	.word z80cpu_ERROR		;CA
	.word z80cpu_ERROR		;CB
	.word z80cpu_ERROR		;CC
	.word z80cpu_ERROR		;CD
	.word z80cpu_SET_1_IaddrI	;CE
	.word z80cpu_ERROR		;CF
	.word z80cpu_ERROR		;D0
	.word z80cpu_ERROR		;D1
	.word z80cpu_ERROR		;D2
	.word z80cpu_ERROR		;D3
	.word z80cpu_ERROR		;D4
	.word z80cpu_ERROR		;D5
	.word z80cpu_SET_2_IaddrI	;D6
	.word z80cpu_ERROR		;D7
	.word z80cpu_ERROR		;D8
	.word z80cpu_ERROR		;D9
	.word z80cpu_ERROR		;DA
	.word z80cpu_ERROR		;DB
	.word z80cpu_ERROR		;DC
	.word z80cpu_ERROR		;DD
	.word z80cpu_SET_3_IaddrI	;DE
	.word z80cpu_ERROR		;DF
	.word z80cpu_ERROR		;E0
	.word z80cpu_ERROR		;E1
	.word z80cpu_ERROR		;E2
	.word z80cpu_ERROR		;E3
	.word z80cpu_ERROR		;E4
	.word z80cpu_ERROR		;E5
	.word z80cpu_SET_4_IaddrI	;E6
	.word z80cpu_ERROR		;E7
	.word z80cpu_ERROR		;E8
	.word z80cpu_ERROR		;E9
	.word z80cpu_ERROR		;EA
	.word z80cpu_ERROR		;EB
	.word z80cpu_ERROR		;EC
	.word z80cpu_ERROR		;ED
	.word z80cpu_SET_5_IaddrI	;EE
	.word z80cpu_ERROR		;EF
	.word z80cpu_ERROR		;F0
	.word z80cpu_ERROR		;F1
	.word z80cpu_ERROR		;F2
	.word z80cpu_ERROR		;F3
	.word z80cpu_ERROR		;F4
	.word z80cpu_ERROR		;F5
	.word z80cpu_SET_6_IaddrI	;F6
	.word z80cpu_ERROR		;F7
	.word z80cpu_ERROR		;F8
	.word z80cpu_ERROR		;F9
	.word z80cpu_ERROR		;FA
	.word z80cpu_ERROR		;FB
	.word z80cpu_ERROR		;FC
	.word z80cpu_ERROR		;FD
	.word z80cpu_SET_7_IaddrI	;FE
	.word z80cpu_ERROR		;FF

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

	.code
	.align 1

;
;	* 無効命令処理ルーチンです。
;	- 実行コンテキスト内から呼ばれることを想定しています。
;	  すなわち、各レジスタには規定の値が保持されていなければいけません。
;	  (詳細は、clipz8ca.hを参照してください。)
;	- 実行コンテキストをZ80CPU構造体に書き戻して実行コンテキストを抜けた後、
;	  C言語版のエラー処理ルーチン本体(z80cpu_error())へジャンプします。
;	  z80cpu_error()は処理を返しません。
;
	.global z80cpu_ERROR
z80cpu_ERROR:
	xcall z80cpu_leave		; 実行コンテキストを書き戻します。
	xjp z80cpu_error		; エラー処理ルーチン本体へジャンプします。

;
;	* 保留割り込みの実行を検査します。
;	- 実行コンテキスト内から呼ばれることを想定しています。
;	  すなわち、各レジスタには規定の値が保持されていなければいけません。
;	  (詳細は、clipz8ca.hを参照してください。)
;	- 実行コンテキストをZ80CPU構造体に書き戻して実行コンテキストを抜けた後、
;	  C言語版の保留割り込み検査ルーチン本体(z80cpu_check_pending())を呼び出します。
;	  z80cpu_check_pending()が処理を返すと、再び実行コンテキストを読み込み、
;	  実行コンテキスト内へ復帰します。
;	  z80cpu_check_pending()はZ80CPU構造体の内容を変化させる可能性があるため、
;	  以上の手順を踏む必要があることに注意してください。
;
	.global z80cpu_CHECK_PENDING
z80cpu_CHECK_PENDING:
	xcall z80cpu_leave		; 実行コンテキストを書き戻します。
	xcall z80cpu_check_pending	; 保留割り込みの実行を検査します。
	xjp   z80cpu_enter		; 実行コンテキストを取り出します。

;
;	実行コンテキストを取り出し、実行コンテキスト内へ入ります。
;
	.global z80cpu_enter
z80cpu_enter:
	xld.w  %CPU, z80cpu		; z80cpuアドレス(固定値)を保持します。
	xld.w  %MEM, z80mem		; z80memアドレス(固定値)を保持します。
	xld.ub %A, [%CPU+_A_]		; Aレジスタを取り出します。
	xld.ub %F, [%CPU+_F_]		; Fレジスタを取り出し、C33形式に変換します。
	ext z80cpu_f2psr@ah
	ext z80cpu_f2psr@al
	ld.ub  %F, [%F]
	xld.uh %PC, [%CPU+_PC_]		; PCを取り出し、ベースアドレスを足します。
	add    %PC, %MEM
	xld.w  %CYCLE, [%CPU+_CYCLE_]	; Cycleを取り出します。
	ret

;
;	実行コンテキストを書き戻し、実行コンテキストから抜けます。
;
	.global z80cpu_leave
z80cpu_leave:
	xld.b [%CPU+_A_], %A		; Aレジスタを書き戻します。
	ext z80cpu_psr2f@ah		; FレジスタをZ80形式に変換し、書き戻します。
	ext z80cpu_psr2f@al
	ld.ub  %t0, [%F]
	xld.b [%CPU+_F_], %t0
	ld.w   %t0, %PC			; PCのベースアドレスを引き、書き戻します。
	sub    %t0, %MEM
	xld.h [%CPU+_PC_], %t0
	xld.w [%CPU+_CYCLE_], %CYCLE	; Cycleを書き戻します。
	ret

;****************************************************************************
;	8-Bit Load Group
;****************************************************************************

	.global z80cpu_LD_A_n
	.global z80cpu_LD_A_A
	.global z80cpu_LD_A_B
	.global z80cpu_LD_A_C
	.global z80cpu_LD_A_D
	.global z80cpu_LD_A_E
	.global z80cpu_LD_A_H
	.global z80cpu_LD_A_L
	.global z80cpu_LD_A_IXH
	.global z80cpu_LD_A_IXL
	.global z80cpu_LD_A_IYH
	.global z80cpu_LD_A_IYL
	.global z80cpu_LD_B_n
	.global z80cpu_LD_B_A
	.global z80cpu_LD_B_B
	.global z80cpu_LD_B_C
	.global z80cpu_LD_B_D
	.global z80cpu_LD_B_E
	.global z80cpu_LD_B_H
	.global z80cpu_LD_B_L
	.global z80cpu_LD_B_IXH
	.global z80cpu_LD_B_IXL
	.global z80cpu_LD_B_IYH
	.global z80cpu_LD_B_IYL
	.global z80cpu_LD_C_n
	.global z80cpu_LD_C_A
	.global z80cpu_LD_C_B
	.global z80cpu_LD_C_C
	.global z80cpu_LD_C_D
	.global z80cpu_LD_C_E
	.global z80cpu_LD_C_H
	.global z80cpu_LD_C_L
	.global z80cpu_LD_C_IXH
	.global z80cpu_LD_C_IXL
	.global z80cpu_LD_C_IYH
	.global z80cpu_LD_C_IYL
	.global z80cpu_LD_D_n
	.global z80cpu_LD_D_A
	.global z80cpu_LD_D_B
	.global z80cpu_LD_D_C
	.global z80cpu_LD_D_D
	.global z80cpu_LD_D_E
	.global z80cpu_LD_D_H
	.global z80cpu_LD_D_L
	.global z80cpu_LD_D_IXH
	.global z80cpu_LD_D_IXL
	.global z80cpu_LD_D_IYH
	.global z80cpu_LD_D_IYL
	.global z80cpu_LD_E_n
	.global z80cpu_LD_E_A
	.global z80cpu_LD_E_B
	.global z80cpu_LD_E_C
	.global z80cpu_LD_E_D
	.global z80cpu_LD_E_E
	.global z80cpu_LD_E_H
	.global z80cpu_LD_E_L
	.global z80cpu_LD_E_IXH
	.global z80cpu_LD_E_IXL
	.global z80cpu_LD_E_IYH
	.global z80cpu_LD_E_IYL
	.global z80cpu_LD_H_n
	.global z80cpu_LD_H_A
	.global z80cpu_LD_H_B
	.global z80cpu_LD_H_C
	.global z80cpu_LD_H_D
	.global z80cpu_LD_H_E
	.global z80cpu_LD_H_H
	.global z80cpu_LD_H_L
	.global z80cpu_LD_L_n
	.global z80cpu_LD_L_A
	.global z80cpu_LD_L_B
	.global z80cpu_LD_L_C
	.global z80cpu_LD_L_D
	.global z80cpu_LD_L_E
	.global z80cpu_LD_L_H
	.global z80cpu_LD_L_L
	.global z80cpu_LD_IXH_n
	.global z80cpu_LD_IXH_A
	.global z80cpu_LD_IXH_B
	.global z80cpu_LD_IXH_C
	.global z80cpu_LD_IXH_D
	.global z80cpu_LD_IXH_E
	.global z80cpu_LD_IXH_IXH
	.global z80cpu_LD_IXH_IXL
	.global z80cpu_LD_IXL_n
	.global z80cpu_LD_IXL_A
	.global z80cpu_LD_IXL_B
	.global z80cpu_LD_IXL_C
	.global z80cpu_LD_IXL_D
	.global z80cpu_LD_IXL_E
	.global z80cpu_LD_IXL_IXH
	.global z80cpu_LD_IXL_IXL
	.global z80cpu_LD_IYH_n
	.global z80cpu_LD_IYH_A
	.global z80cpu_LD_IYH_B
	.global z80cpu_LD_IYH_C
	.global z80cpu_LD_IYH_D
	.global z80cpu_LD_IYH_E
	.global z80cpu_LD_IYH_IYH
	.global z80cpu_LD_IYH_IYL
	.global z80cpu_LD_IYL_n
	.global z80cpu_LD_IYL_A
	.global z80cpu_LD_IYL_B
	.global z80cpu_LD_IYL_C
	.global z80cpu_LD_IYL_D
	.global z80cpu_LD_IYL_E
	.global z80cpu_LD_IYL_IYH
	.global z80cpu_LD_IYL_IYL

	.global z80cpu_LD_A_IlmI
	.global z80cpu_LD_A_IBCI
	.global z80cpu_LD_A_IDEI
	.global z80cpu_LD_A_IHLI
	.global z80cpu_LD_B_IHLI
	.global z80cpu_LD_C_IHLI
	.global z80cpu_LD_D_IHLI
	.global z80cpu_LD_E_IHLI
	.global z80cpu_LD_H_IHLI
	.global z80cpu_LD_L_IHLI
	.global z80cpu_LD_A_IIX_dI
	.global z80cpu_LD_B_IIX_dI
	.global z80cpu_LD_C_IIX_dI
	.global z80cpu_LD_D_IIX_dI
	.global z80cpu_LD_E_IIX_dI
	.global z80cpu_LD_H_IIX_dI
	.global z80cpu_LD_L_IIX_dI
	.global z80cpu_LD_A_IIY_dI
	.global z80cpu_LD_B_IIY_dI
	.global z80cpu_LD_C_IIY_dI
	.global z80cpu_LD_D_IIY_dI
	.global z80cpu_LD_E_IIY_dI
	.global z80cpu_LD_H_IIY_dI
	.global z80cpu_LD_L_IIY_dI

	.global z80cpu_LD_IlmI_A
	.global z80cpu_LD_IHLI_n
	.global z80cpu_LD_IBCI_A
	.global z80cpu_LD_IDEI_A
	.global z80cpu_LD_IHLI_A
	.global z80cpu_LD_IHLI_B
	.global z80cpu_LD_IHLI_C
	.global z80cpu_LD_IHLI_D
	.global z80cpu_LD_IHLI_E
	.global z80cpu_LD_IHLI_H
	.global z80cpu_LD_IHLI_L
	.global z80cpu_LD_IIX_dI_n
	.global z80cpu_LD_IIY_dI_n
	.global z80cpu_LD_IIX_dI_A
	.global z80cpu_LD_IIX_dI_B
	.global z80cpu_LD_IIX_dI_C
	.global z80cpu_LD_IIX_dI_D
	.global z80cpu_LD_IIX_dI_E
	.global z80cpu_LD_IIX_dI_H
	.global z80cpu_LD_IIX_dI_L
	.global z80cpu_LD_IIY_dI_A
	.global z80cpu_LD_IIY_dI_B
	.global z80cpu_LD_IIY_dI_C
	.global z80cpu_LD_IIY_dI_D
	.global z80cpu_LD_IIY_dI_E
	.global z80cpu_LD_IIY_dI_H
	.global z80cpu_LD_IIY_dI_L

	.global z80cpu_LD_A_I
	.global z80cpu_LD_A_R
	.global z80cpu_LD_I_A
	.global z80cpu_LD_R_A

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

z80cpu_LD_A_n:
	ld.ub %A, [%PC]+		; %A = n
	ret.d
	sub %CYCLE, CYCLE_LD_A_n	; *delay*

z80cpu_LD_A_A:
	ld.w %A, %A			; %A = A
	ret.d
	sub %CYCLE, CYCLE_LD_A_A	; *delay*

#macro LD_A_r $1, $2
	xld.ub %A, [%CPU+$2]		; %A = r
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_A_B:
	LD_A_r CYCLE_LD_A_B, B
z80cpu_LD_A_C:
	LD_A_r CYCLE_LD_A_C, C
z80cpu_LD_A_D:
	LD_A_r CYCLE_LD_A_D, D
z80cpu_LD_A_E:
	LD_A_r CYCLE_LD_A_E, E
z80cpu_LD_A_H:
	LD_A_r CYCLE_LD_A_H, H
z80cpu_LD_A_L:
	LD_A_r CYCLE_LD_A_L, L
z80cpu_LD_A_IXH:
	LD_A_r CYCLE_LD_A_IXH, IXH
z80cpu_LD_A_IXL:
	LD_A_r CYCLE_LD_A_IXL, IXL
z80cpu_LD_A_IYH:
	LD_A_r CYCLE_LD_A_IYH, IYH
z80cpu_LD_A_IYL:
	LD_A_r CYCLE_LD_A_IYL, IYL

#macro LD_r_n $1, $2
	ld.ub  %t0, [%PC]+		; %t0 = n
	xld.b [%CPU+$2], %t0		; r = n
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_B_n:
	LD_r_n CYCLE_LD_B_n, B
z80cpu_LD_C_n:
	LD_r_n CYCLE_LD_C_n, C
z80cpu_LD_D_n:
	LD_r_n CYCLE_LD_D_n, D
z80cpu_LD_E_n:
	LD_r_n CYCLE_LD_E_n, E
z80cpu_LD_H_n:
	LD_r_n CYCLE_LD_H_n, H
z80cpu_LD_L_n:
	LD_r_n CYCLE_LD_L_n, L
z80cpu_LD_IXH_n:
	LD_r_n CYCLE_LD_IXH_n, IXH
z80cpu_LD_IXL_n:
	LD_r_n CYCLE_LD_IXL_n, IXL
z80cpu_LD_IYH_n:
	LD_r_n CYCLE_LD_IYH_n, IYH
z80cpu_LD_IYL_n:
	LD_r_n CYCLE_LD_IYL_n, IYL

#macro LD_r_A $1, $2
	xld.b [%CPU+$2], %A		; r = A
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_B_A:
	LD_r_A CYCLE_LD_B_A, B
z80cpu_LD_C_A:
	LD_r_A CYCLE_LD_C_A, C
z80cpu_LD_D_A:
	LD_r_A CYCLE_LD_D_A, D
z80cpu_LD_E_A:
	LD_r_A CYCLE_LD_E_A, E
z80cpu_LD_H_A:
	LD_r_A CYCLE_LD_H_A, H
z80cpu_LD_L_A:
	LD_r_A CYCLE_LD_L_A, L
z80cpu_LD_IXH_A:
	LD_r_A CYCLE_LD_IXH_A, IXH
z80cpu_LD_IXL_A:
	LD_r_A CYCLE_LD_IXL_A, IXL
z80cpu_LD_IYH_A:
	LD_r_A CYCLE_LD_IYH_A, IYH
z80cpu_LD_IYL_A:
	LD_r_A CYCLE_LD_IYL_A, IYL

#macro LD_r_s $1, $2, $3
	xld.ub %t0, [%CPU+$3]		; %t0 = s
	xld.b [%CPU+$2], %t0		; r = s
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_B_B:
	LD_r_s CYCLE_LD_B_B, B, B
z80cpu_LD_B_C:
	LD_r_s CYCLE_LD_B_C, B, C
z80cpu_LD_B_D:
	LD_r_s CYCLE_LD_B_D, B, D
z80cpu_LD_B_E:
	LD_r_s CYCLE_LD_B_E, B, E
z80cpu_LD_B_H:
	LD_r_s CYCLE_LD_B_H, B, H
z80cpu_LD_B_L:
	LD_r_s CYCLE_LD_B_L, B, L
z80cpu_LD_B_IXH:
	LD_r_s CYCLE_LD_B_IXH, B, IXH
z80cpu_LD_B_IXL:
	LD_r_s CYCLE_LD_B_IXL, B, IXL
z80cpu_LD_B_IYH:
	LD_r_s CYCLE_LD_B_IYH, B, IYH
z80cpu_LD_B_IYL:
	LD_r_s CYCLE_LD_B_IYL, B, IYL

z80cpu_LD_C_B:
	LD_r_s CYCLE_LD_C_B, C, B
z80cpu_LD_C_C:
	LD_r_s CYCLE_LD_C_C, C, C
z80cpu_LD_C_D:
	LD_r_s CYCLE_LD_C_D, C, D
z80cpu_LD_C_E:
	LD_r_s CYCLE_LD_C_E, C, E
z80cpu_LD_C_H:
	LD_r_s CYCLE_LD_C_H, C, H
z80cpu_LD_C_L:
	LD_r_s CYCLE_LD_C_L, C, L
z80cpu_LD_C_IXH:
	LD_r_s CYCLE_LD_C_IXH, C, IXH
z80cpu_LD_C_IXL:
	LD_r_s CYCLE_LD_C_IXL, C, IXL
z80cpu_LD_C_IYH:
	LD_r_s CYCLE_LD_C_IYH, C, IYH
z80cpu_LD_C_IYL:
	LD_r_s CYCLE_LD_C_IYL, C, IYL

z80cpu_LD_D_B:
	LD_r_s CYCLE_LD_D_B, D, B
z80cpu_LD_D_C:
	LD_r_s CYCLE_LD_D_C, D, C
z80cpu_LD_D_D:
	LD_r_s CYCLE_LD_D_D, D, D
z80cpu_LD_D_E:
	LD_r_s CYCLE_LD_D_E, D, E
z80cpu_LD_D_H:
	LD_r_s CYCLE_LD_D_H, D, H
z80cpu_LD_D_L:
	LD_r_s CYCLE_LD_D_L, D, L
z80cpu_LD_D_IXH:
	LD_r_s CYCLE_LD_D_IXH, D, IXH
z80cpu_LD_D_IXL:
	LD_r_s CYCLE_LD_D_IXL, D, IXL
z80cpu_LD_D_IYH:
	LD_r_s CYCLE_LD_D_IYH, D, IYH
z80cpu_LD_D_IYL:
	LD_r_s CYCLE_LD_D_IYL, D, IYL

z80cpu_LD_E_B:
	LD_r_s CYCLE_LD_E_B, E, B
z80cpu_LD_E_C:
	LD_r_s CYCLE_LD_E_C, E, C
z80cpu_LD_E_D:
	LD_r_s CYCLE_LD_E_D, E, D
z80cpu_LD_E_E:
	LD_r_s CYCLE_LD_E_E, E, E
z80cpu_LD_E_H:
	LD_r_s CYCLE_LD_E_H, E, H
z80cpu_LD_E_L:
	LD_r_s CYCLE_LD_E_L, E, L
z80cpu_LD_E_IXH:
	LD_r_s CYCLE_LD_E_IXH, E, IXH
z80cpu_LD_E_IXL:
	LD_r_s CYCLE_LD_E_IXL, E, IXL
z80cpu_LD_E_IYH:
	LD_r_s CYCLE_LD_E_IYH, E, IYH
z80cpu_LD_E_IYL:
	LD_r_s CYCLE_LD_E_IYL, E, IYL

z80cpu_LD_H_B:
	LD_r_s CYCLE_LD_H_B, H, B
z80cpu_LD_H_C:
	LD_r_s CYCLE_LD_H_C, H, C
z80cpu_LD_H_D:
	LD_r_s CYCLE_LD_H_D, H, D
z80cpu_LD_H_E:
	LD_r_s CYCLE_LD_H_E, H, E
z80cpu_LD_H_H:
	LD_r_s CYCLE_LD_H_H, H, H
z80cpu_LD_H_L:
	LD_r_s CYCLE_LD_H_L, H, L

z80cpu_LD_L_B:
	LD_r_s CYCLE_LD_L_B, L, B
z80cpu_LD_L_C:
	LD_r_s CYCLE_LD_L_C, L, C
z80cpu_LD_L_D:
	LD_r_s CYCLE_LD_L_D, L, D
z80cpu_LD_L_E:
	LD_r_s CYCLE_LD_L_E, L, E
z80cpu_LD_L_H:
	LD_r_s CYCLE_LD_L_H, L, H
z80cpu_LD_L_L:
	LD_r_s CYCLE_LD_L_L, L, L

z80cpu_LD_IXH_B:
	LD_r_s CYCLE_LD_IXH_B, IXH, B
z80cpu_LD_IXH_C:
	LD_r_s CYCLE_LD_IXH_C, IXH, C
z80cpu_LD_IXH_D:
	LD_r_s CYCLE_LD_IXH_D, IXH, D
z80cpu_LD_IXH_E:
	LD_r_s CYCLE_LD_IXH_E, IXH, E
z80cpu_LD_IXH_IXH:
	LD_r_s CYCLE_LD_IXH_IXH, IXH, IXH
z80cpu_LD_IXH_IXL:
	LD_r_s CYCLE_LD_IXH_IXL, IXH, IXL

z80cpu_LD_IXL_B:
	LD_r_s CYCLE_LD_IXL_B, IXL, B
z80cpu_LD_IXL_C:
	LD_r_s CYCLE_LD_IXL_C, IXL, C
z80cpu_LD_IXL_D:
	LD_r_s CYCLE_LD_IXL_D, IXL, D
z80cpu_LD_IXL_E:
	LD_r_s CYCLE_LD_IXL_E, IXL, E
z80cpu_LD_IXL_IXH:
	LD_r_s CYCLE_LD_IXL_IXH, IXL, IXH
z80cpu_LD_IXL_IXL:
	LD_r_s CYCLE_LD_IXL_IXL, IXL, IXL

z80cpu_LD_IYH_B:
	LD_r_s CYCLE_LD_IYH_B, IYH, B
z80cpu_LD_IYH_C:
	LD_r_s CYCLE_LD_IYH_C, IYH, C
z80cpu_LD_IYH_D:
	LD_r_s CYCLE_LD_IYH_D, IYH, D
z80cpu_LD_IYH_E:
	LD_r_s CYCLE_LD_IYH_E, IYH, E
z80cpu_LD_IYH_IYH:
	LD_r_s CYCLE_LD_IYH_IYH, IYH, IYH
z80cpu_LD_IYH_IYL:
	LD_r_s CYCLE_LD_IYH_IYL, IYH, IYL

z80cpu_LD_IYL_B:
	LD_r_s CYCLE_LD_IYL_B, IYL, B
z80cpu_LD_IYL_C:
	LD_r_s CYCLE_LD_IYL_C, IYL, C
z80cpu_LD_IYL_D:
	LD_r_s CYCLE_LD_IYL_D, IYL, D
z80cpu_LD_IYL_E:
	LD_r_s CYCLE_LD_IYL_E, IYL, E
z80cpu_LD_IYL_IYH:
	LD_r_s CYCLE_LD_IYL_IYH, IYL, IYH
z80cpu_LD_IYL_IYL:
	LD_r_s CYCLE_LD_IYL_IYL, IYL, IYL

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

z80cpu_LD_A_IlmI:
	ld.ub %t0, [%PC]+		; %t0 = m
	ld.ub %t1, [%PC]+		; %t1 = l
	xsll  %t1, 8			; %t0 = lm
	or    %t0, %t1
	add   %t0, %MEM			; %t0 = mem+lm
	ld.ub %A, [%t0]			; %A = [mem+lm]
	ret.d
	sub %CYCLE, CYCLE_LD_A_IlmI	; *delay*

#macro LD_A_IrrI $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	add    %t0, %MEM		; %t0 = mem+rr
	ld.ub  %A, [%t0]		; %A = [mem+rr]
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_A_IBCI:
	LD_A_IrrI CYCLE_LD_A_IBCI, BC
z80cpu_LD_A_IDEI:
	LD_A_IrrI CYCLE_LD_A_IDEI, DE
z80cpu_LD_A_IHLI:
	LD_A_IrrI CYCLE_LD_A_IHLI, HL

#macro LD_r_IHLI $1, $2
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	ld.ub  %t0, [%t0]		; %t0 = [mem+HL]
	xld.b [%CPU+$2], %t0		; r = [mem+HL]
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_B_IHLI:
	LD_r_IHLI CYCLE_LD_B_IHLI, B
z80cpu_LD_C_IHLI:
	LD_r_IHLI CYCLE_LD_C_IHLI, C
z80cpu_LD_D_IHLI:
	LD_r_IHLI CYCLE_LD_D_IHLI, D
z80cpu_LD_E_IHLI:
	LD_r_IHLI CYCLE_LD_E_IHLI, E
z80cpu_LD_H_IHLI:
	LD_r_IHLI CYCLE_LD_H_IHLI, H
z80cpu_LD_L_IHLI:
	LD_r_IHLI CYCLE_LD_L_IHLI, L

#macro LD_A_Irr_dI $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = rr+d
	add    %t0, %MEM		; %t0 = mem+rr+d
	ld.ub  %A, [%t0]		; %A = [mem+rr+d]
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_A_IIX_dI:
	LD_A_Irr_dI CYCLE_LD_A_IIX_dI, IX
z80cpu_LD_A_IIY_dI:
	LD_A_Irr_dI CYCLE_LD_A_IIY_dI, IY

#macro LD_r_Iss_dI $1, $2, $3
	xld.uh %t0, [%CPU+$3]		; %t0 = ss
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = ss+d
	add    %t0, %MEM		; %t0 = mem+ss+d
	ld.ub  %t0, [%t0]		; %t0 = [mem+ss+d]
	xld.b [%CPU+$2], %t0		; r = [mem+ss+d]
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_B_IIX_dI:
	LD_r_Iss_dI CYCLE_LD_B_IIX_dI, B, IX
z80cpu_LD_C_IIX_dI:
	LD_r_Iss_dI CYCLE_LD_C_IIX_dI, C, IX
z80cpu_LD_D_IIX_dI:
	LD_r_Iss_dI CYCLE_LD_D_IIX_dI, D, IX
z80cpu_LD_E_IIX_dI:
	LD_r_Iss_dI CYCLE_LD_E_IIX_dI, E, IX
z80cpu_LD_H_IIX_dI:
	LD_r_Iss_dI CYCLE_LD_H_IIX_dI, H, IX
z80cpu_LD_L_IIX_dI:
	LD_r_Iss_dI CYCLE_LD_L_IIX_dI, L, IX

z80cpu_LD_B_IIY_dI:
	LD_r_Iss_dI CYCLE_LD_B_IIY_dI, B, IY
z80cpu_LD_C_IIY_dI:
	LD_r_Iss_dI CYCLE_LD_C_IIY_dI, C, IY
z80cpu_LD_D_IIY_dI:
	LD_r_Iss_dI CYCLE_LD_D_IIY_dI, D, IY
z80cpu_LD_E_IIY_dI:
	LD_r_Iss_dI CYCLE_LD_E_IIY_dI, E, IY
z80cpu_LD_H_IIY_dI:
	LD_r_Iss_dI CYCLE_LD_H_IIY_dI, H, IY
z80cpu_LD_L_IIY_dI:
	LD_r_Iss_dI CYCLE_LD_L_IIY_dI, L, IY

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

z80cpu_LD_IlmI_A:
	ld.ub %t0, [%PC]+		; %t0 = m
	ld.ub %t1, [%PC]+		; %t1 = l
	xsll  %t1, 8			; %t0 = lm
	or    %t0, %t1
	add   %t0, %MEM			; %t0 = mem+lm
	ld.b [%t0], %A			; [mem+lm] = A
	ret.d
	sub %CYCLE, CYCLE_LD_IlmI_A	; *delay*

z80cpu_LD_IHLI_n:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	ld.ub  %t1, [%PC]+		; %t1 = n
	xld.b [%t0], %t1		; [mem+HL] = n
	ret.d
	sub %CYCLE, CYCLE_LD_IHLI_n	; *delay*

#macro LD_IrrI_A $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	add    %t0, %MEM		; %t0 = mem+rr
	xld.b [%t0], %A			; [mem+rr] = A
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_IBCI_A:
	LD_IrrI_A CYCLE_LD_IBCI_A, BC
z80cpu_LD_IDEI_A:
	LD_IrrI_A CYCLE_LD_IDEI_A, DE
z80cpu_LD_IHLI_A:
	LD_IrrI_A CYCLE_LD_IHLI_A, HL

#macro LD_IHLI_r $1, $2
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	xld.ub %t1, [%CPU+$2]		; %t1 = r
	xld.b [%t0], %t1		; [mem+HL] = r
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_IHLI_B:
	LD_IHLI_r CYCLE_LD_IHLI_B, B
z80cpu_LD_IHLI_C:
	LD_IHLI_r CYCLE_LD_IHLI_C, C
z80cpu_LD_IHLI_D:
	LD_IHLI_r CYCLE_LD_IHLI_D, D
z80cpu_LD_IHLI_E:
	LD_IHLI_r CYCLE_LD_IHLI_E, E
z80cpu_LD_IHLI_H:
	LD_IHLI_r CYCLE_LD_IHLI_H, H
z80cpu_LD_IHLI_L:
	LD_IHLI_r CYCLE_LD_IHLI_L, L

#macro LD_Irr_dI_n $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = rr+d
	add    %t0, %MEM		; %t0 = mem+rr+d
	ld.ub  %t1, [%PC]+		; %t1 = n
	xld.b [%t0], %t1		; [mem+rr+d] = n
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_IIX_dI_n:
	LD_Irr_dI_n CYCLE_LD_IIX_dI_n, IX
z80cpu_LD_IIY_dI_n:
	LD_Irr_dI_n CYCLE_LD_IIY_dI_n, IY

#macro LD_Irr_dI_A $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = rr+d
	add    %t0, %MEM		; %t0 = mem+rr+d
	xld.b [%t0], %A			; [mem+rr+d] = A
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_IIX_dI_A:
	LD_Irr_dI_A CYCLE_LD_IIX_dI_A, IX
z80cpu_LD_IIY_dI_A:
	LD_Irr_dI_A CYCLE_LD_IIY_dI_A, IY

#macro LD_Irr_dI_s $1, $2, $3
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = rr+d
	add    %t0, %MEM		; %t0 = mem+rr+d
	xld.ub %t1, [%CPU+$3]		; %t1 = s
	xld.b [%t0], %t1		; [mem+rr+d] = s
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_IIX_dI_B:
	LD_Irr_dI_s CYCLE_LD_IIX_dI_B, IX, B
z80cpu_LD_IIX_dI_C:
	LD_Irr_dI_s CYCLE_LD_IIX_dI_C, IX, C
z80cpu_LD_IIX_dI_D:
	LD_Irr_dI_s CYCLE_LD_IIX_dI_D, IX, D
z80cpu_LD_IIX_dI_E:
	LD_Irr_dI_s CYCLE_LD_IIX_dI_E, IX, E
z80cpu_LD_IIX_dI_H:
	LD_Irr_dI_s CYCLE_LD_IIX_dI_H, IX, H
z80cpu_LD_IIX_dI_L:
	LD_Irr_dI_s CYCLE_LD_IIX_dI_L, IX, L

z80cpu_LD_IIY_dI_B:
	LD_Irr_dI_s CYCLE_LD_IIY_dI_B, IY, B
z80cpu_LD_IIY_dI_C:
	LD_Irr_dI_s CYCLE_LD_IIY_dI_C, IY, C
z80cpu_LD_IIY_dI_D:
	LD_Irr_dI_s CYCLE_LD_IIY_dI_D, IY, D
z80cpu_LD_IIY_dI_E:
	LD_Irr_dI_s CYCLE_LD_IIY_dI_E, IY, E
z80cpu_LD_IIY_dI_H:
	LD_Irr_dI_s CYCLE_LD_IIY_dI_H, IY, H
z80cpu_LD_IIY_dI_L:
	LD_Irr_dI_s CYCLE_LD_IIY_dI_L, IY, L

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

;
;	S	is set if I-Register is negative, reset otherwise
;	Z	is set if I-Register is zero, reset otherwise
;	H	is reset
;	P/V	contains contents of IFF2
;	N	is reset
;	C	is not affected
;
z80cpu_LD_A_I:
	xld.ub %A, [%CPU+I]		; %A = I
	;
	xand   %F, %F, CF		; %F = F(00C000)
	swap   %t0, %A			; %t0[31:24] = A
	or     %t0, %t0			; test A
	ld.w   %t0, %psr		; %t0 = F
	xand   %t0, %t0, ZF|SF		; %t0 = F(0000ZS)
	xbtst [%CPU+IFF2], 0		; test IFF2
	jreq.d 3
	or     %F, %t0			; %F = F(00C0ZS) *delay*
	or     %F, PF			; %F = F(00CPZS) (skip?)
	;
	ret.d
	sub %CYCLE, CYCLE_LD_A_I	; *delay*

;
;	S	is set if R-Register is negative, reset otherwise
;	Z	is set if R-Register is zero, reset otherwise
;	H	is reset
;	P/V	contains contents of IFF2
;	N	is reset
;	C	is not affected
;
z80cpu_LD_A_R:
	xld.ub %A, [%CPU+R]		; %A = R
	;
	xand   %F, %F, CF		; %F = F(00C000)
	swap   %t0, %A			; %t0[31:24] = A
	or     %t0, %t0			; test A
	ld.w   %t0, %psr		; %t0 = F
	xand   %t0, %t0, ZF|SF		; %t0 = F(0000ZS)
	xbtst [%CPU+IFF2], 0		; test IFF2
	jreq.d 3
	or     %F, %t0			; %F = F(00C0ZS) *delay*
	or     %F, PF			; %F = F(00CPZS) (skip?)
	;
	xand   %t0, %A , 0x80		; %t0 = R[7]
	xadd   %t1, %A , 1		; %t1 = R+1
	xand   %t1, %t1, 0x7f		; %t1 = R+1[6:0]
	or     %t0, %t1			; %t0 = R[7]|R+1[6:0]
	xld.b [%CPU+R], %t0		; R = R[7]|R+1[6:0]
	;
	ret.d
	sub %CYCLE, CYCLE_LD_A_R	; *delay*

z80cpu_LD_I_A:
	xld.b [%CPU+I], %A		; I = A
	ret.d
	sub %CYCLE, CYCLE_LD_I_A	; *delay*

z80cpu_LD_R_A:
	xld.b [%CPU+R], %A		; R = A
	ret.d
	sub %CYCLE, CYCLE_LD_R_A	; *delay*

;****************************************************************************
;	16-Bit Load Group
;****************************************************************************

	.global z80cpu_LD_SP_HL
	.global z80cpu_LD_SP_IX
	.global z80cpu_LD_SP_IY

	.global z80cpu_LD_BC_lm
	.global z80cpu_LD_DE_lm
	.global z80cpu_LD_HL_lm
	.global z80cpu_LD_SP_lm
	.global z80cpu_LD_IX_lm
	.global z80cpu_LD_IY_lm

	.global z80cpu_LD_BC_IlmI
	.global z80cpu_LD_DE_IlmI
	.global z80cpu_LD_HL_IlmI
	.global z80cpu_LD_SP_IlmI
	.global z80cpu_LD_IX_IlmI
	.global z80cpu_LD_IY_IlmI

	.global z80cpu_LD_IlmI_BC
	.global z80cpu_LD_IlmI_DE
	.global z80cpu_LD_IlmI_HL
	.global z80cpu_LD_IlmI_SP
	.global z80cpu_LD_IlmI_IX
	.global z80cpu_LD_IlmI_IY

	.global z80cpu_POP_AF
	.global z80cpu_POP_BC
	.global z80cpu_POP_DE
	.global z80cpu_POP_HL
	.global z80cpu_POP_IX
	.global z80cpu_POP_IY

	.global z80cpu_PUSH_AF
	.global z80cpu_PUSH_BC
	.global z80cpu_PUSH_DE
	.global z80cpu_PUSH_HL
	.global z80cpu_PUSH_IX
	.global z80cpu_PUSH_IY

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

#macro LD_SP_rr $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	xld.h [%CPU+SP], %t0		; SP = rr
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_SP_HL:
	LD_SP_rr CYCLE_LD_SP_HL, HL
z80cpu_LD_SP_IX:
	LD_SP_rr CYCLE_LD_SP_IX, IX
z80cpu_LD_SP_IY:
	LD_SP_rr CYCLE_LD_SP_IY, IY

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

#macro LD_rr_lm $1, $2
	ld.ub  %t0, [%PC]+		; %t0 = m
	ld.ub  %t1, [%PC]+		; %t1 = l
	xsll   %t1, 8			; %t0 = lm
	or     %t0, %t1
	xld.h [%CPU+$2], %t0		; rr = lm
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_BC_lm:
	LD_rr_lm CYCLE_LD_BC_lm, BC
z80cpu_LD_DE_lm:
	LD_rr_lm CYCLE_LD_DE_lm, DE
z80cpu_LD_HL_lm:
	LD_rr_lm CYCLE_LD_HL_lm, HL
z80cpu_LD_SP_lm:
	LD_rr_lm CYCLE_LD_SP_lm, SP
z80cpu_LD_IX_lm:
	LD_rr_lm CYCLE_LD_IX_lm, IX
z80cpu_LD_IY_lm:
	LD_rr_lm CYCLE_LD_IY_lm, IY

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

#macro LD_rr_IlmI $1, $2
	ld.ub  %t0, [%PC]+		; %t0 = m
	ld.ub  %t1, [%PC]+		; %t1 = l
	xsll   %t1, 8			; %t0 = lm
	or     %t0, %t1
	add    %t0, %MEM		; %t0 = mem+lm
	ld.ub  %t1, [%t0]+		; %t1 = [mem+lm+0]
	ld.ub  %t2, [%t0]		; %t2 = [mem+lm+1]
	xsll   %t2, 8			; %t1 = [mem+lm+0]|[mem+lm+1]<<8
	or     %t1, %t2
	xld.h [%CPU+$2], %t1		; rr = [mem+lm+0]|[mem+lm+1]<<8
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_BC_IlmI:
	LD_rr_IlmI CYCLE_LD_BC_IlmI, BC
z80cpu_LD_DE_IlmI:
	LD_rr_IlmI CYCLE_LD_DE_IlmI, DE
z80cpu_LD_HL_IlmI:
	LD_rr_IlmI CYCLE_LD_HL_IlmI, HL
z80cpu_LD_SP_IlmI:
	LD_rr_IlmI CYCLE_LD_SP_IlmI, SP
z80cpu_LD_IX_IlmI:
	LD_rr_IlmI CYCLE_LD_IX_IlmI, IX
z80cpu_LD_IY_IlmI:
	LD_rr_IlmI CYCLE_LD_IY_IlmI, IY

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

#macro LD_IlmI_rr $1, $2
	ld.ub  %t0, [%PC]+		; %t0 = m
	ld.ub  %t1, [%PC]+		; %t1 = l
	xsll   %t1, 8			; %t0 = lm
	or     %t0, %t1
	add    %t0, %MEM		; %t0 = mem+lm
	xld.uh %t1, [%CPU+$2]		; %t1 = rr
	ld.b  [%t0]+, %t1		; [mem+lm+0] = lo(lm)
	xsrl   %t1, 8			; [mem+lm+1] = hi(lm)
	ld.b  [%t0], %t1
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_LD_IlmI_BC:
	LD_IlmI_rr CYCLE_LD_IlmI_BC, BC
z80cpu_LD_IlmI_DE:
	LD_IlmI_rr CYCLE_LD_IlmI_DE, DE
z80cpu_LD_IlmI_HL:
	LD_IlmI_rr CYCLE_LD_IlmI_HL, HL
z80cpu_LD_IlmI_SP:
	LD_IlmI_rr CYCLE_LD_IlmI_SP, SP
z80cpu_LD_IlmI_IX:
	LD_IlmI_rr CYCLE_LD_IlmI_IX, IX
z80cpu_LD_IlmI_IY:
	LD_IlmI_rr CYCLE_LD_IlmI_IY, IY

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

z80cpu_POP_AF:
	xcall z80cpu_pop		; %a0 = AF
	ld.ub %F, %a0			; %F = F(Z80)
	ext z80cpu_f2psr@ah		; %F = F(C33)
	ext z80cpu_f2psr@al
	ld.ub %F, [%F]
	xsrl  %a0, 8			; %A = A
	ld.w  %A, %a0
	ret.d
	sub %CYCLE, CYCLE_POP_AF	; *delay*

#macro POP_rr $1, $2
	xcall z80cpu_pop		; %a0 = rr
	xld.h [%CPU+$2], %a0		; rr = rr
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_POP_BC:
	POP_rr CYCLE_POP_BC, BC
z80cpu_POP_DE:
	POP_rr CYCLE_POP_DE, DE
z80cpu_POP_HL:
	POP_rr CYCLE_POP_HL, HL
z80cpu_POP_IX:
	POP_rr CYCLE_POP_IX, IX
z80cpu_POP_IY:
	POP_rr CYCLE_POP_IY, IY

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

z80cpu_PUSH_AF:
	ext z80cpu_psr2f@ah		; %a0 = F(Z80)
	ext z80cpu_psr2f@al
	ld.ub %a0, [%F]
	ld.w  %t0, %A			; %t0 = A
	xsll  %t0, 8			; %a0 = AF
	xcall.d z80cpu_push		; push AF
	or    %a0, %t0			; *delay*
	ret.d
	sub %CYCLE, CYCLE_PUSH_AF	; *delay*

#macro PUSH_rr $1, $2
	xld.uh %a0, [%CPU+$2]		; %a0 = rr
	xcall z80cpu_push		; push rr
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_PUSH_BC:
	PUSH_rr CYCLE_PUSH_BC, BC
z80cpu_PUSH_DE:
	PUSH_rr CYCLE_PUSH_DE, DE
z80cpu_PUSH_HL:
	PUSH_rr CYCLE_PUSH_HL, HL
z80cpu_PUSH_IX:
	PUSH_rr CYCLE_PUSH_IX, IX
z80cpu_PUSH_IY:
	PUSH_rr CYCLE_PUSH_IY, IY

;****************************************************************************
;	Exchange, Block Transfer, and Search Group
;****************************************************************************

	.global z80cpu_EX_ISPI_HL
	.global z80cpu_EX_ISPI_IX
	.global z80cpu_EX_ISPI_IY
	.global z80cpu_EX_AF_AF2
	.global z80cpu_EX_DE_HL
	.global z80cpu_EXX

	.global z80cpu_LDI
	.global z80cpu_LDIR
	.global z80cpu_LDD
	.global z80cpu_LDDR

	.global z80cpu_CPI
	.global z80cpu_CPIR
	.global z80cpu_CPD
	.global z80cpu_CPDR

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

#macro EX_ISPI_rr $1, $2
	xld.uh %t0, [%CPU+SP]		; %t0 = SP
	add    %t0, %MEM		; %t0 = mem+SP+0
	xld.ub %t1, [%CPU+$2+0]		; %t1 = lo(rr)
	ld.ub  %t2, [%t0]		; %t2 = [mem+SP+0]
	ld.b  [%t0]+, %t1		; [mem+SP+0] = lo(rr), %t0 = mem+SP+1
	xld.b [%CPU+$2+0], %t2		; lo(rr) = [mem+SP+0]
	xld.ub %t1, [%CPU+$2+1]		; %t1 = hi(rr)
	ld.ub  %t2, [%t0]		; %t2 = [mem+SP+1]
	ld.b  [%t0], %t1		; [mem+SP+1] = hi(rr)
	xld.b [%CPU+$2+1], %t2		; hi(rr) = [mem+SP+1]
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_EX_ISPI_HL:
	EX_ISPI_rr CYCLE_EX_ISPI_HL, HL
z80cpu_EX_ISPI_IX:
	EX_ISPI_rr CYCLE_EX_ISPI_IX, IX
z80cpu_EX_ISPI_IY:
	EX_ISPI_rr CYCLE_EX_ISPI_IY, IY

z80cpu_EX_AF_AF2:
	xld.ub %t0, [%CPU+AF2+0]	; %t0 = F'(Z80) ----+
	xld.ub %t1, [%CPU+AF2+1]	; %t1 = A' -------+ |
	ext z80cpu_psr2f@ah		; %F = F(Z80) --+ | |
	ext z80cpu_psr2f@al		;               | | |
	ld.ub  %F, [%F]			;               | | |
	xld.b [%CPU+AF2+0], %F		; F' = F(Z80) <-+ | |
	xld.b [%CPU+AF2+1], %A		; A' = A          | |
	ext z80cpu_f2psr@ah		; %F = F'(C33) <--|-+
	ext z80cpu_f2psr@al		;                 |
	ld.ub  %F, [%t0]		;                 |
	ld.ub  %A,  %t1			; %A = A' <-------+
	ret.d
	sub %CYCLE, CYCLE_EX_AF_AF2	; *delay*

z80cpu_EX_DE_HL:
	xld.uh %t0, [%CPU+DE]		; %t0 = DE
	xld.uh %t1, [%CPU+HL]		; %t1 = HL
	xld.h [%CPU+HL], %t0		; HL = DE
	xld.h [%CPU+DE], %t1		; DE = HL
	ret.d
	sub %CYCLE, CYCLE_EX_DE_HL	; *delay*

z80cpu_EXX:
	xld.uh %t0, [%CPU+BC]		; %t0 = BC
	xld.uh %t1, [%CPU+BC2]		; %t1 = BC'
	xld.h [%CPU+BC2], %t0		; BC' = BC
	xld.h [%CPU+BC], %t1		; BC = BC'
	xld.uh %t0, [%CPU+DE]		; %t0 = DE
	xld.uh %t1, [%CPU+DE2]		; %t1 = DE'
	xld.h [%CPU+DE2], %t0		; DE' = DE
	xld.h [%CPU+DE], %t1		; DE = DE'
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	xld.uh %t1, [%CPU+HL2]		; %t1 = HL'
	xld.h [%CPU+HL2], %t0		; HL' = HL
	xld.h [%CPU+HL], %t1		; HL = HL'
	ret.d
	sub %CYCLE, CYCLE_EXX		; *delay*

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

;
;	S	is not affected
;	Z	is not affected
;	H	is reset
;	P/V	is set if BC-1 is not 0, reset otherwise
;	N	is reset
;	C	is not affected
;
z80cpu_LDI:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	xld.uh %t1, [%CPU+DE]		; %t1 = DE
	xld.uh %t2, [%CPU+BC]		; %t2 = BC
	add    %t0, %MEM		; %t0 = mem+HL
	add    %t1, %MEM		; %t1 = mem+DE
	ld.b   %t3, [%t0]+		; %t3 = [mem+HL], %t0 = mem+HL+1
	ld.b  [%t1]+, %t3		; [mem+DE] = %t3, %t1 = mem+DE+1
	sub    %t0, %MEM		; %t0 = HL+1
	sub    %t1, %MEM		; %t1 = DE+1
	sub    %t2, 1			; %t2 = BC-1
	jreq.d 3
	and    %F, CF|ZF|SF		; %F = F(00C0ZS) *delay*
	add    %F, PF			; %F = F(00CPZS) (skip?)
	xld.h [%CPU+HL], %t0		; HL = HL+1
	xld.h [%CPU+DE], %t1		; DE = DE+1
	xld.h [%CPU+BC], %t2		; BC = BC-1
	ret.d
	sub %CYCLE, CYCLE_LDI		; *delay*

;
;	S	is not affected
;	Z	is not affected
;	H	is reset
;	P/V	is reset
;	N	is reset
;	C	is not affected
;
; [note]
;	* BC-1==0の場合、LDIRの消費サイクル数はLDIと同じです。
;	  従って、LDIRの中でCycleを減らす必要はありません。
;	* BC-1!=0の場合、LDIRの消費サイクル数はLDI+5です。
;	  LDIR命令を繰り返すために、自身の2バイト分戻ります。
;
z80cpu_LDIR:
	xcall z80cpu_LDI		; LDI
	xand %r9, %F, PF
	jreq 3
	sub  %PC, 2			; (skip?)
	sub  %CYCLE, 5			; (skip?)
	ret

;
;	S	is not affected
;	Z	is not affected
;	H	is reset
;	P/V	is set if BC-1 is not 0, reset otherwise
;	N	is reset
;	C	is not affected
;
z80cpu_LDD:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	xld.uh %t1, [%CPU+DE]		; %t1 = DE
	xld.uh %t2, [%CPU+BC]		; %t2 = BC
	add    %t0, %MEM		; %t0 = mem+HL
	add    %t1, %MEM		; %t1 = mem+DE
	ld.b   %t3, [%t0]		; %t3 = [mem+HL]
	sub    %t0, 1			; %t0 = mem+HL-1
	ld.b  [%t1], %t3		; [mem+DE] = %t3
	sub    %t1, 1			; %t1 = mem+DE-1
	sub    %t0, %MEM		; %t0 = HL-1
	sub    %t1, %MEM		; %t1 = DE-1
	sub    %t2, 1			; %t2 = BC-1
	jreq.d 3
	and    %F, CF|ZF|SF		; %F = F(00C0ZS) *delay*
	add    %F, PF			; %F = F(00CPZS) (skip?)
	xld.h [%CPU+HL], %t0		; HL = HL-1
	xld.h [%CPU+DE], %t1		; DE = DE-1
	xld.h [%CPU+BC], %t2		; BC = BC-1
	ret.d
	sub %CYCLE, CYCLE_LDD		; *delay*

;
;	S	is not affected
;	Z	is not affected
;	H	is reset
;	P/V	is reset
;	N	is reset
;	C	is not affected
;
; [note]
;	* BC-1==0の場合、LDDRの消費サイクル数はLDDと同じです。
;	  従って、LDDRの中でCycleを減らす必要はありません。
;	* BC-1!=0の場合、LDDRの消費サイクル数はLDD+5です。
;	  LDDR命令を繰り返すために、自身の2バイト分戻ります。
;
z80cpu_LDDR:
	xcall z80cpu_LDD		; LDD
	xand %r9, %F, PF
	jreq 3
	sub  %PC, 2			; (skip?)
	sub  %CYCLE, 5			; (skip?)
	ret

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

;
;	S	is set if result is negative, reset otherwise
;	Z	is set if A is (HL), reset otherwise
;	H	is set if borrow from bit 4, reset otherwise
;	P/V	is set if BC-1 is not 0, reset otherwise
;	N	is set
;	C	is not affected
;
z80cpu_CPI:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	ld.ub  %a0, [%t0]+		; %a0 = [mem+HL], %t0 = mem+HL+1
	sub    %t0, %MEM		; %t0 = HL+1
	xld.h [%CPU+HL], %t0		; HL  = HL+1
	xcall.d z80cpu_cp		; CP %a0
	ld.w   %s0, %F			; %s0 = F *delay*
	;
	xld.uh %t0, [%CPU+BC]		; %t0 = BC
	xand   %F, %F, ~(CF|PF)		; %F  = F(NH00ZS)
	xand   %s0, %s0, CF		; %s0 = F(00C000)
	xsub   %t0, %t0, 1		; %t0 = BC-1
	jreq.d 3
	or     %F, %s0			; %F = F(NHC0ZS) *delay*
	or     %F, PF			; %F = F(NHCPZS) (skip?)
	xld.h [%CPU+BC], %t0		; BC = BC-1
	ret.d
	sub %CYCLE, CYCLE_CPI		; *delay*

;
;	S	is set if result is negative, reset otherwise
;	Z	is set if A equals (HL), reset otherwise
;	H	is set if borrow from bit 4, reset otherwise
;	P/V	is set if BC-1 is not 0, reset otherwise
;	N	is set
;	C	is not affected
;
; [note]
;	* BC-1==0の場合、CPIRの消費サイクル数はCPIと同じです。
;	  従って、CPIRの中でCycleを減らす必要はありません。
;	* BC-1!=0の場合、CPIRの消費サイクル数はCPI+5です。
;	  CPIR命令を繰り返すために、自身の2バイト分戻ります。
;
z80cpu_CPIR:
	xcall z80cpu_CPI		; CPI
	xand %t0, %F, PF|ZF
	xcmp %t0, PF
	jrne 3
	sub  %PC, 2			; (skip?)
	sub  %CYCLE, 5			; (skip?)
	ret

;
;	S	is set if result is negative, reset otherwise
;	Z	is set if A equals (HL), reset otherwise
;	H	is set if borrow from bit 4, reset otherwise
;	P/V	is set if BC-1 is not 0, reset otherwise
;	N	is set
;	C	is not affected
;
z80cpu_CPD:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	ld.ub  %a0, [%t0]		; %a0 = [mem+HL]
	sub    %t0, 1			; %t0 = mem+HL-1
	sub    %t0, %MEM		; %t0 = HL-1
	xld.h [%CPU+HL], %t0		; HL  = HL-1
	xcall.d z80cpu_cp		; CP %a0
	ld.w   %s0, %F			; %s0 = F *delay*
	;
	xld.uh %t0, [%CPU+BC]		; %t0 = BC
	xand   %F, %F, ~(CF|PF)		; %F  = F(NH00ZS)
	xand   %s0, %s0, CF		; %s0 = F(00C000)
	xsub   %t0, %t0, 1		; %t0 = BC-1
	jreq.d 3
	or     %F, %s0			; %F = F(NHC0ZS) *delay*
	or     %F, PF			; %F = F(NHCPZS) (skip?)
	xld.h [%CPU+BC], %t0		; BC = BC-1
	ret.d
	sub %CYCLE, CYCLE_CPD		; *delay*

;
;	S	is set if result is negative, reset otherwise
;	Z	is set if A equals (HL), reset otherwise
;	H	is set if borrow from bit 4, reset otherwise
;	P/V	is set if BC-1 is not 0, reset otherwise
;	N	is set
;	C	is not affected
;
; [note]
;	* BC-1==0の場合、CPDRの消費サイクル数はCPDと同じです。
;	  従って、CPDRの中でCycleを減らす必要はありません。
;	* BC-1!=0の場合、CPDRの消費サイクル数はCPD+5です。
;	  CPDR命令を繰り返すために、自身の2バイト分戻ります。
;
z80cpu_CPDR:
	xcall z80cpu_CPD		; CPD
	xand %t0, %F, PF|ZF
	xcmp %t0, PF
	jrne 3
	sub  %PC, 2			; (skip?)
	sub  %CYCLE, 5			; (skip?)
	ret 

;****************************************************************************
;	8-Bit Arithmetic Group
;****************************************************************************

	.global z80cpu_ADD_A_n
	.global z80cpu_ADD_A_A
	.global z80cpu_ADD_A_B
	.global z80cpu_ADD_A_C
	.global z80cpu_ADD_A_D
	.global z80cpu_ADD_A_E
	.global z80cpu_ADD_A_H
	.global z80cpu_ADD_A_L
	.global z80cpu_ADD_A_IXH
	.global z80cpu_ADD_A_IXL
	.global z80cpu_ADD_A_IYH
	.global z80cpu_ADD_A_IYL
	.global z80cpu_ADD_A_IHLI
	.global z80cpu_ADD_A_IIX_dI
	.global z80cpu_ADD_A_IIY_dI

	.global z80cpu_ADC_A_n
	.global z80cpu_ADC_A_A
	.global z80cpu_ADC_A_B
	.global z80cpu_ADC_A_C
	.global z80cpu_ADC_A_D
	.global z80cpu_ADC_A_E
	.global z80cpu_ADC_A_H
	.global z80cpu_ADC_A_L
	.global z80cpu_ADC_A_IXH
	.global z80cpu_ADC_A_IXL
	.global z80cpu_ADC_A_IYH
	.global z80cpu_ADC_A_IYL
	.global z80cpu_ADC_A_IHLI
	.global z80cpu_ADC_A_IIX_dI
	.global z80cpu_ADC_A_IIY_dI

	.global z80cpu_SUB_n
	.global z80cpu_SUB_A
	.global z80cpu_SUB_B
	.global z80cpu_SUB_C
	.global z80cpu_SUB_D
	.global z80cpu_SUB_E
	.global z80cpu_SUB_H
	.global z80cpu_SUB_L
	.global z80cpu_SUB_IXH
	.global z80cpu_SUB_IXL
	.global z80cpu_SUB_IYH
	.global z80cpu_SUB_IYL
	.global z80cpu_SUB_IHLI
	.global z80cpu_SUB_IIX_dI
	.global z80cpu_SUB_IIY_dI

	.global z80cpu_SBC_A_n
	.global z80cpu_SBC_A_A
	.global z80cpu_SBC_A_B
	.global z80cpu_SBC_A_C
	.global z80cpu_SBC_A_D
	.global z80cpu_SBC_A_E
	.global z80cpu_SBC_A_H
	.global z80cpu_SBC_A_L
	.global z80cpu_SBC_A_IXH
	.global z80cpu_SBC_A_IXL
	.global z80cpu_SBC_A_IYH
	.global z80cpu_SBC_A_IYL
	.global z80cpu_SBC_A_IHLI
	.global z80cpu_SBC_A_IIX_dI
	.global z80cpu_SBC_A_IIY_dI

	.global z80cpu_AND_n
	.global z80cpu_AND_A
	.global z80cpu_AND_B
	.global z80cpu_AND_C
	.global z80cpu_AND_D
	.global z80cpu_AND_E
	.global z80cpu_AND_H
	.global z80cpu_AND_L
	.global z80cpu_AND_IXH
	.global z80cpu_AND_IXL
	.global z80cpu_AND_IYH
	.global z80cpu_AND_IYL
	.global z80cpu_AND_IHLI
	.global z80cpu_AND_IIX_dI
	.global z80cpu_AND_IIY_dI

	.global z80cpu_OR_n
	.global z80cpu_OR_A
	.global z80cpu_OR_B
	.global z80cpu_OR_C
	.global z80cpu_OR_D
	.global z80cpu_OR_E
	.global z80cpu_OR_H
	.global z80cpu_OR_L
	.global z80cpu_OR_IXH
	.global z80cpu_OR_IXL
	.global z80cpu_OR_IYH
	.global z80cpu_OR_IYL
	.global z80cpu_OR_IHLI
	.global z80cpu_OR_IIX_dI
	.global z80cpu_OR_IIY_dI

	.global z80cpu_XOR_n
	.global z80cpu_XOR_A
	.global z80cpu_XOR_B
	.global z80cpu_XOR_C
	.global z80cpu_XOR_D
	.global z80cpu_XOR_E
	.global z80cpu_XOR_H
	.global z80cpu_XOR_L
	.global z80cpu_XOR_IXH
	.global z80cpu_XOR_IXL
	.global z80cpu_XOR_IYH
	.global z80cpu_XOR_IYL
	.global z80cpu_XOR_IHLI
	.global z80cpu_XOR_IIX_dI
	.global z80cpu_XOR_IIY_dI

	.global z80cpu_CP_n
	.global z80cpu_CP_A
	.global z80cpu_CP_B
	.global z80cpu_CP_C
	.global z80cpu_CP_D
	.global z80cpu_CP_E
	.global z80cpu_CP_H
	.global z80cpu_CP_L
	.global z80cpu_CP_IXH
	.global z80cpu_CP_IXL
	.global z80cpu_CP_IYH
	.global z80cpu_CP_IYL
	.global z80cpu_CP_IHLI
	.global z80cpu_CP_IIX_dI
	.global z80cpu_CP_IIY_dI

	.global z80cpu_INC_A
	.global z80cpu_INC_B
	.global z80cpu_INC_C
	.global z80cpu_INC_D
	.global z80cpu_INC_E
	.global z80cpu_INC_H
	.global z80cpu_INC_L
	.global z80cpu_INC_IXH
	.global z80cpu_INC_IXL
	.global z80cpu_INC_IYH
	.global z80cpu_INC_IYL
	.global z80cpu_INC_IHLI
	.global z80cpu_INC_IIX_dI
	.global z80cpu_INC_IIY_dI

	.global z80cpu_DEC_A
	.global z80cpu_DEC_B
	.global z80cpu_DEC_C
	.global z80cpu_DEC_D
	.global z80cpu_DEC_E
	.global z80cpu_DEC_H
	.global z80cpu_DEC_L
	.global z80cpu_DEC_IXH
	.global z80cpu_DEC_IXL
	.global z80cpu_DEC_IYH	
	.global z80cpu_DEC_IYL
	.global z80cpu_DEC_IHLI
	.global z80cpu_DEC_IIX_dI
	.global z80cpu_DEC_IIY_dI

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

z80cpu_ADD_A_n:
	ld.ub %a0, [%PC]+		; %a0 = n
	xjp.d z80cpu_add8
	sub %CYCLE, CYCLE_ADD_A_n	; *delay*

z80cpu_ADD_A_A:
	ld.w %a0, %A			; %a0 = A
	xjp.d z80cpu_add8
	sub %CYCLE, CYCLE_ADD_A_A	; *delay*

#macro ADD_A_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xjp.d z80cpu_add8
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_ADD_A_B:
	ADD_A_r CYCLE_ADD_A_B, B
z80cpu_ADD_A_C:
	ADD_A_r CYCLE_ADD_A_C, C
z80cpu_ADD_A_D:
	ADD_A_r CYCLE_ADD_A_D, D
z80cpu_ADD_A_E:
	ADD_A_r CYCLE_ADD_A_E, E
z80cpu_ADD_A_H:
	ADD_A_r CYCLE_ADD_A_H, H
z80cpu_ADD_A_L:
	ADD_A_r CYCLE_ADD_A_L, L
z80cpu_ADD_A_IXH:
	ADD_A_r CYCLE_ADD_A_IXH, IXH
z80cpu_ADD_A_IXL:
	ADD_A_r CYCLE_ADD_A_IXL, IXL
z80cpu_ADD_A_IYH:
	ADD_A_r CYCLE_ADD_A_IYH, IYH
z80cpu_ADD_A_IYL:
	ADD_A_r CYCLE_ADD_A_IYL, IYL

z80cpu_ADD_A_IHLI:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	ld.ub  %a0, [%t0]		; %a0 = [mem+HL]
	xjp.d z80cpu_add8
	sub %CYCLE, CYCLE_ADD_A_IHLI	; *delay*

#macro ADD_A_Irr_dI $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = rr+d
	add    %t0, %MEM		; %t0 = mem+rr+d
	ld.ub  %a0, [%t0]		; %a0 = [mem+rr+d]
	xjp.d z80cpu_add8
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_ADD_A_IIX_dI:
	ADD_A_Irr_dI CYCLE_ADD_A_IIX_dI, IX
z80cpu_ADD_A_IIY_dI:
	ADD_A_Irr_dI CYCLE_ADD_A_IIY_dI, IY

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

z80cpu_ADC_A_n:
	ld.ub %a0, [%PC]+		; %a0 = n
	xjp.d z80cpu_adc8
	sub %CYCLE, CYCLE_ADC_A_n	; *delay*

z80cpu_ADC_A_A:
	ld.w %a0, %A			; %a0 = A
	xjp.d z80cpu_adc8
	sub %CYCLE, CYCLE_ADC_A_A	; *delay*

#macro ADC_A_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xjp.d z80cpu_adc8
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_ADC_A_B:
	ADC_A_r CYCLE_ADC_A_B, B
z80cpu_ADC_A_C:
	ADC_A_r CYCLE_ADC_A_C, C
z80cpu_ADC_A_D:
	ADC_A_r CYCLE_ADC_A_D, D
z80cpu_ADC_A_E:
	ADC_A_r CYCLE_ADC_A_E, E
z80cpu_ADC_A_H:
	ADC_A_r CYCLE_ADC_A_H, H
z80cpu_ADC_A_L:
	ADC_A_r CYCLE_ADC_A_L, L
z80cpu_ADC_A_IXH:
	ADC_A_r CYCLE_ADC_A_IXH, IXH
z80cpu_ADC_A_IXL:
	ADC_A_r CYCLE_ADC_A_IXL, IXL
z80cpu_ADC_A_IYH:
	ADC_A_r CYCLE_ADC_A_IYH, IYH
z80cpu_ADC_A_IYL:
	ADC_A_r CYCLE_ADC_A_IYL, IYL

z80cpu_ADC_A_IHLI:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	ld.ub  %a0, [%t0]		; %a0 = [mem+HL]
	xjp.d z80cpu_adc8
	sub %CYCLE, CYCLE_ADC_A_IHLI	; *delay*

#macro ADC_A_Irr_dI $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = rr+d
	add    %t0, %MEM		; %t0 = mem+rr+d
	ld.ub  %a0, [%t0]		; %a0 = [mem+rr+d]
	xjp.d z80cpu_adc8
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_ADC_A_IIX_dI:
	ADC_A_Irr_dI CYCLE_ADC_A_IIX_dI, IX
z80cpu_ADC_A_IIY_dI:
	ADC_A_Irr_dI CYCLE_ADC_A_IIY_dI, IY

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

z80cpu_SUB_n:
	ld.ub %a0, [%PC]+		; %a0 = n
	xjp.d z80cpu_sub8
	sub %CYCLE, CYCLE_SUB_n	; *delay*

z80cpu_SUB_A:
	ld.w %a0, %A			; %a0 = A
	xjp.d z80cpu_sub8
	sub %CYCLE, CYCLE_SUB_A	; *delay*

#macro SUB_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xjp.d z80cpu_sub8
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_SUB_B:
	SUB_r CYCLE_SUB_B, B
z80cpu_SUB_C:
	SUB_r CYCLE_SUB_C, C
z80cpu_SUB_D:
	SUB_r CYCLE_SUB_D, D
z80cpu_SUB_E:
	SUB_r CYCLE_SUB_E, E
z80cpu_SUB_H:
	SUB_r CYCLE_SUB_H, H
z80cpu_SUB_L:
	SUB_r CYCLE_SUB_L, L
z80cpu_SUB_IXH:
	SUB_r CYCLE_SUB_IXH, IXH
z80cpu_SUB_IXL:
	SUB_r CYCLE_SUB_IXL, IXL
z80cpu_SUB_IYH:
	SUB_r CYCLE_SUB_IYH, IYH
z80cpu_SUB_IYL:
	SUB_r CYCLE_SUB_IYL, IYL

z80cpu_SUB_IHLI:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	ld.ub  %a0, [%t0]		; %a0 = [mem+HL]
	xjp.d z80cpu_sub8
	sub %CYCLE, CYCLE_SUB_IHLI	; *delay*

#macro SUB_Irr_dI $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = rr+d
	add    %t0, %MEM		; %t0 = mem+rr+d
	ld.ub  %a0, [%t0]		; %a0 = [mem+rr+d]
	xjp.d z80cpu_sub8
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_SUB_IIX_dI:
	SUB_Irr_dI CYCLE_SUB_IIX_dI, IX
z80cpu_SUB_IIY_dI:
	SUB_Irr_dI CYCLE_SUB_IIY_dI, IY

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

z80cpu_SBC_A_n:
	ld.ub %a0, [%PC]+		; %a0 = n
	xjp.d z80cpu_sbc8
	sub %CYCLE, CYCLE_SBC_A_n	; *delay*

z80cpu_SBC_A_A:
	ld.w %a0, %A			; %a0 = A
	xjp.d z80cpu_sbc8
	sub %CYCLE, CYCLE_SBC_A_A	; *delay*

#macro SBC_A_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xjp.d z80cpu_sbc8
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_SBC_A_B:
	SBC_A_r CYCLE_SBC_A_B, B
z80cpu_SBC_A_C:
	SBC_A_r CYCLE_SBC_A_C, C
z80cpu_SBC_A_D:
	SBC_A_r CYCLE_SBC_A_D, D
z80cpu_SBC_A_E:
	SBC_A_r CYCLE_SBC_A_E, E
z80cpu_SBC_A_H:
	SBC_A_r CYCLE_SBC_A_H, H
z80cpu_SBC_A_L:
	SBC_A_r CYCLE_SBC_A_L, L
z80cpu_SBC_A_IXH:
	SBC_A_r CYCLE_SBC_A_IXH, IXH
z80cpu_SBC_A_IXL:
	SBC_A_r CYCLE_SBC_A_IXL, IXL
z80cpu_SBC_A_IYH:
	SBC_A_r CYCLE_SBC_A_IYH, IYH
z80cpu_SBC_A_IYL:
	SBC_A_r CYCLE_SBC_A_IYL, IYL

z80cpu_SBC_A_IHLI:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	ld.ub  %a0, [%t0]		; %t0 = [mme+HL]
	xjp.d z80cpu_sbc8
	sub %CYCLE, CYCLE_SBC_A_IHLI	; *delay*

#macro SBC_A_Irr_dI $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = rr+d
	add    %t0, %MEM		; %t0 = mem+rr+d
	ld.ub  %a0, [%t0]		; %a0 = [mem+rr+d]
	xjp.d z80cpu_sbc8
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_SBC_A_IIX_dI:
	SBC_A_Irr_dI CYCLE_SBC_A_IIX_dI, IX
z80cpu_SBC_A_IIY_dI:
	SBC_A_Irr_dI CYCLE_SBC_A_IIY_dI, IY

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

z80cpu_AND_n:
	ld.ub %a0, [%PC]+		; %a0 = n
	xjp.d z80cpu_and
	sub %CYCLE, CYCLE_AND_n		; *delay*

z80cpu_AND_A:
	ld.w %a0, %A			; %a0 = A
	xjp.d z80cpu_and
	sub %CYCLE, CYCLE_AND_A		; *delay*

#macro AND_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xjp.d z80cpu_and
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_AND_B:
	AND_r CYCLE_AND_B, B
z80cpu_AND_C:
	AND_r CYCLE_AND_C, C
z80cpu_AND_D:
	AND_r CYCLE_AND_D, D
z80cpu_AND_E:
	AND_r CYCLE_AND_E, E
z80cpu_AND_H:
	AND_r CYCLE_AND_H, H
z80cpu_AND_L:
	AND_r CYCLE_AND_L, L
z80cpu_AND_IXH:
	AND_r CYCLE_AND_IXH, IXH
z80cpu_AND_IXL:
	AND_r CYCLE_AND_IXL, IXL
z80cpu_AND_IYH:
	AND_r CYCLE_AND_IYH, IYH
z80cpu_AND_IYL:
	AND_r CYCLE_AND_IYL, IYL

z80cpu_AND_IHLI:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	ld.ub  %a0, [%t0]		; %a0 = [mem+HL]
	xjp.d z80cpu_and
	sub %CYCLE, CYCLE_AND_IHLI	; *delay*

#macro AND_Irr_dI $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = rr+d
	add    %t0, %MEM		; %t0 = mem+rr+d
	ld.ub  %a0, [%t0]		; %a0 = [mem+rr+d]
	xjp.d z80cpu_and
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_AND_IIX_dI:
	AND_Irr_dI CYCLE_AND_IIX_dI, IX
z80cpu_AND_IIY_dI:
	AND_Irr_dI CYCLE_AND_IIY_dI, IY

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

z80cpu_OR_n:
	ld.ub %a0, [%PC]+		; %a0 = n
	xjp.d z80cpu_or
	sub %CYCLE, CYCLE_OR_n		; *delay*

z80cpu_OR_A:
	ld.w %a0, %A			; %a0 = A
	xjp.d z80cpu_or
	sub %CYCLE, CYCLE_OR_A		; *delay*

#macro OR_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xjp.d z80cpu_or
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_OR_B:
	OR_r CYCLE_OR_B, B
z80cpu_OR_C:
	OR_r CYCLE_OR_C, C
z80cpu_OR_D:
	OR_r CYCLE_OR_D, D
z80cpu_OR_E:
	OR_r CYCLE_OR_E, E
z80cpu_OR_H:
	OR_r CYCLE_OR_H, H
z80cpu_OR_L:
	OR_r CYCLE_OR_L, L
z80cpu_OR_IXH:
	OR_r CYCLE_OR_IXH, IXH
z80cpu_OR_IXL:
	OR_r CYCLE_OR_IXL, IXL
z80cpu_OR_IYH:
	OR_r CYCLE_OR_IYH, IYH
z80cpu_OR_IYL:
	OR_r CYCLE_OR_IYL, IYL

z80cpu_OR_IHLI:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	ld.ub  %a0, [%t0]		; %a0 = [mem+HL]
	xjp.d z80cpu_or
	sub %CYCLE, CYCLE_OR_IHLI	; *delay*

#macro OR_Irr_dI $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = rr+d
	add    %t0, %MEM		; %t0 = mem+rr+d
	ld.ub  %a0, [%t0]		; %a0 = [mem+rr+d]
	xjp.d z80cpu_or
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_OR_IIX_dI:
	OR_Irr_dI CYCLE_OR_IIX_dI, IX
z80cpu_OR_IIY_dI:
	OR_Irr_dI CYCLE_OR_IIY_dI, IY

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

z80cpu_XOR_n:
	ld.ub %a0, [%PC]+		; %a0 = n
	xjp.d z80cpu_xor
	sub %CYCLE, CYCLE_XOR_n		; *delay*

z80cpu_XOR_A:
	ld.w %a0, %A			; %a0 = A
	xjp.d z80cpu_xor
	sub %CYCLE, CYCLE_XOR_A		; *delay*

#macro XOR_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xjp.d z80cpu_xor
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_XOR_B:
	XOR_r CYCLE_XOR_B, B
z80cpu_XOR_C:
	XOR_r CYCLE_XOR_C, C
z80cpu_XOR_D:
	XOR_r CYCLE_XOR_D, D
z80cpu_XOR_E:
	XOR_r CYCLE_XOR_E, E
z80cpu_XOR_H:
	XOR_r CYCLE_XOR_H, H
z80cpu_XOR_L:
	XOR_r CYCLE_XOR_L, L
z80cpu_XOR_IXH:
	XOR_r CYCLE_XOR_IXH, IXH
z80cpu_XOR_IXL:
	XOR_r CYCLE_XOR_IXL, IXL
z80cpu_XOR_IYH:
	XOR_r CYCLE_XOR_IYH, IYH
z80cpu_XOR_IYL:
	XOR_r CYCLE_XOR_IYL, IYL

z80cpu_XOR_IHLI:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	ld.ub  %a0, [%t0]		; %t0 = [mem+HL]
	xjp.d z80cpu_xor
	sub %CYCLE, CYCLE_XOR_IHLI	; *delay*

#macro XOR_Irr_dI $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = rr+d
	add    %t0, %MEM		; %t0 = mem+rr+d
	ld.ub  %a0, [%t0]		; %a0 = [mem+rr+d]
	xjp.d z80cpu_xor
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_XOR_IIX_dI:
	XOR_Irr_dI CYCLE_XOR_IIX_dI, IX
z80cpu_XOR_IIY_dI:
	XOR_Irr_dI CYCLE_XOR_IIY_dI, IY

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

z80cpu_CP_n:
	ld.ub %a0, [%PC]+		; %a0 = n
	xjp.d z80cpu_cp
	sub %CYCLE, CYCLE_CP_n		; *delay*

z80cpu_CP_A:
	ld.w %a0, %A			; %a0 = A
	xjp.d z80cpu_cp
	sub %CYCLE, CYCLE_CP_A		; *delay*

#macro CP_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xjp.d z80cpu_cp
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_CP_B:
	CP_r CYCLE_CP_B, B
z80cpu_CP_C:
	CP_r CYCLE_CP_C, C
z80cpu_CP_D:
	CP_r CYCLE_CP_D, D
z80cpu_CP_E:
	CP_r CYCLE_CP_E, E
z80cpu_CP_H:
	CP_r CYCLE_CP_H, H
z80cpu_CP_L:
	CP_r CYCLE_CP_L, L
z80cpu_CP_IXH:
	CP_r CYCLE_CP_IXH, IXH
z80cpu_CP_IXL:
	CP_r CYCLE_CP_IXL, IXL
z80cpu_CP_IYH:
	CP_r CYCLE_CP_IYH, IYH
z80cpu_CP_IYL:
	CP_r CYCLE_CP_IYL, IYL

z80cpu_CP_IHLI:
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	ld.ub  %a0, [%t0]		; %t0 = [mem+HL]
	xjp.d z80cpu_cp
	sub %CYCLE, CYCLE_CP_IHLI	; *delay*

#macro CP_Irr_dI $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	ld.b   %t1, [%PC]+		; %t1 = d (signed)
	add    %t0, %t1			; %t0 = rr+d
	add    %t0, %MEM		; %t0 = mem+rr+d
	ld.ub  %a0, [%t0]		; %a0 = [mem+rr+d]
	xjp.d z80cpu_cp
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_CP_IIX_dI:
	CP_Irr_dI CYCLE_CP_IIX_dI, IX
z80cpu_CP_IIY_dI:
	CP_Irr_dI CYCLE_CP_IIY_dI, IY

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

z80cpu_INC_A:
	xcall.d z80cpu_inc8
	ld.w %a0, %A			; %a0 = A *delay*
	ld.w %A, %a0			; A = A+1
	ret.d
	sub %CYCLE, CYCLE_INC_A	; *delay*

#macro INC_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xcall z80cpu_inc8
	xld.b [%CPU+$2], %a0		; r = r+1
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_INC_B:
	INC_r CYCLE_INC_B, B
z80cpu_INC_C:
	INC_r CYCLE_INC_C, C
z80cpu_INC_D:
	INC_r CYCLE_INC_D, D
z80cpu_INC_E:
	INC_r CYCLE_INC_E, E
z80cpu_INC_H:
	INC_r CYCLE_INC_H, H
z80cpu_INC_L:
	INC_r CYCLE_INC_L, L
z80cpu_INC_IXH:
	INC_r CYCLE_INC_IXH, IXH
z80cpu_INC_IXL:
	INC_r CYCLE_INC_IXL, IXL
z80cpu_INC_IYH:
	INC_r CYCLE_INC_IYH, IYH
z80cpu_INC_IYL:
	INC_r CYCLE_INC_IYL, IYL

z80cpu_INC_IHLI:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	add    %s0, %MEM		; %s0 = mem+HL
	ld.ub  %a0, [%s0]		; %a0 = [mem+HL]
	xcall z80cpu_inc8
	ld.b  [%s0], %a0		; [mem+HL] = [mem+HL]+1
	ret.d
	sub %CYCLE, CYCLE_INC_IHLI	; *delay*

#macro INC_Irr_dI $1, $2
	xld.uh %s0, [%CPU+$2]		; %s0 = rr
	ld.b   %t0, [%PC]+		; %t0 = d (signed)
	add    %s0, %t0			; %s0 = rr+d
	add    %s0, %MEM		; %s0 = mem+rr+d
	ld.ub  %a0, [%s0]		; %a0 = [mem+rr+d]
	xcall z80cpu_inc8
	ld.b  [%s0], %a0		; [mem+rr+d] = [mem+rr+d]+1
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_INC_IIX_dI:
	INC_Irr_dI CYCLE_INC_IIX_dI, IX
z80cpu_INC_IIY_dI:
	INC_Irr_dI CYCLE_INC_IIY_dI, IY

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

z80cpu_DEC_A:
	xcall.d z80cpu_dec8
	ld.w %a0, %A			; %a0 = A *delay*
	ld.w %A, %a0			; A = A-1
	ret.d
	sub %CYCLE, CYCLE_DEC_A	; *delay*

#macro DEC_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xcall z80cpu_dec8
	xld.b [%CPU+$2], %a0		; r = r+1
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_DEC_B:
	DEC_r CYCLE_DEC_B, B
z80cpu_DEC_C:
	DEC_r CYCLE_DEC_C, C
z80cpu_DEC_D:
	DEC_r CYCLE_DEC_D, D
z80cpu_DEC_E:
	DEC_r CYCLE_DEC_E, E
z80cpu_DEC_H:
	DEC_r CYCLE_DEC_H, H
z80cpu_DEC_L:
	DEC_r CYCLE_DEC_L, L
z80cpu_DEC_IXH:
	DEC_r CYCLE_DEC_IXH, IXH
z80cpu_DEC_IXL:
	DEC_r CYCLE_DEC_IXL, IXL
z80cpu_DEC_IYH:
	DEC_r CYCLE_DEC_IYH, IYH
z80cpu_DEC_IYL:
	DEC_r CYCLE_DEC_IYL, IYL

z80cpu_DEC_IHLI:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	add    %s0, %MEM		; %s0 = mem+HL
	ld.ub  %a0, [%s0]		; %a0 = [mem+HL]
	xcall z80cpu_dec8
	ld.b  [%s0], %a0		; [mem+HL] = [mem+HL]-1
	ret.d
	sub %CYCLE, CYCLE_DEC_IHLI	; *delay*

#macro DEC_Irr_dI $1, $2
	xld.uh %s0, [%CPU+$2]		; %s0 = rr
	ld.b   %t0, [%PC]+		; %t0 = d (signed)
	add    %s0, %t0			; %s0 = rr+d
	add    %s0, %MEM		; %s0 = mem+rr+d
	ld.ub  %a0, [%s0]		; %a0 = [mem+rr+d]
	xcall z80cpu_dec8		
	ld.b  [%s0], %a0		; [mem+rr+d] = [mem+rr+d]-1
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_DEC_IIX_dI:
	DEC_Irr_dI CYCLE_DEC_IIX_dI, IX
z80cpu_DEC_IIY_dI:
	DEC_Irr_dI CYCLE_DEC_IIY_dI, IY

;****************************************************************************
;	General-Purpose Arithmetic and CPU Control Group
;****************************************************************************

	.global z80cpu_DAA
	.global z80cpu_CPL
	.global z80cpu_NEG
	.global z80cpu_CCF
	.global z80cpu_SCF
	.global z80cpu_NOP
	.global z80cpu_HALT
	.global z80cpu_DI
	.global z80cpu_EI
	.global z80cpu_IM_0
	.global z80cpu_IM_1
	.global z80cpu_IM_2

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

;
; [note]
;	* 遅くても構わないので、C言語版を呼び出しています。
;	  いずれ、アセンブラ化する予定です。
;
z80cpu_DAA:
	xcall z80cpu_leave		; 実行コンテキストを書き戻します。
	xcall z80cpu_daa
	xjp.d z80cpu_enter		; 実行コンテキストを取り出します。
	sub %CYCLE, CYCLE_DAA		; *delay*

;
;	S	is not affected
;	Z	is not affected
;	H	is set
;	P/V	is not affected
;	N	is set
;	C	is not affected
;
z80cpu_CPL:
	not   %A, %A			; %A = ~A (signed)
	ld.ub %A, %A			; %A = ~A (unsigned)
	xoor  %F, %F, NF|HF		; %F = F(NH----) (N,Hが既に1の可能性があるので、xadd不可)
	ret.d
	sub %CYCLE, CYCLE_CPL		; *delay*

;
;	S	is set if result is negative, reset otherwise
;	Z	is set if result is 0, reset otherwise
;	H	is set if borrow from bit 4, reset otherwise
;	P/V	is set if Accumulator was 80H before operation, reset otherwise
;	N	is set
;	C	is set if Accumulator was not 00H before operation, reset otherwise
;
; [note]
;	* フラグ変化は"SUB 0, A"に等価です。
;	  (推測ですけれど、たぶん間違いないと思います。)
;
z80cpu_NEG:
	ld.w %a0, %A			; %a0 = A
	xcall.d z80cpu_sub8
	ld.w %A, 0			; %A = 0 *delay*
	ret.d
	sub %CYCLE, CYCLE_NEG		; *delay*

;
;	S	is not affected
;	Z	is not affected
;	H	previous carry is copied
;	P/V	is not affected
;	N	is reset
;	C	is set if CY was 0 before operation, reset otherwise
;
z80cpu_CCF:
	xand %r9, %F, CF		; test F(C)
	jreq.d 3
	ld.w %t0, CF			; if F(C)=0 then %t0 = F(00C000) *delay*
	ld.w %t0, HF			; if F(C)=1 then %t0 = F(0H0000) (skip?)
	xand %F, %F, ~(NF|HF|CF)	; %F = F(000PZS)
	or   %F, %t0			; %F = F(0HCPZS)
	ret.d
	sub %CYCLE, CYCLE_CCF		; *delay*

;
;	S	is not affected
;	Z	is not affected
;	H	is reset
;	P/V	is not affected
;	N	is reset
;	C	is set
;
z80cpu_SCF:
	xand %F, %F, ~(NF|HF)		; %F = F(00-PZS)
	xoor %F, %F, CF			; %F = F(001PZS) (Cが既に1の可能性があるので、xadd不可)
	ret.d
	sub %CYCLE, CYCLE_SCF		; *delay*

z80cpu_NOP:
	;** no job **
	ret.d
	sub %CYCLE, CYCLE_NOP		; *delay*

z80cpu_HALT:
	xbset [%CPU+HALT], 0		; HALT = 1
	ret.d
	ld.w %CYCLE, 0			; (残りCycleを0にしてrunを抜けます) *delay*

z80cpu_DI:
	xbclr [%CPU+IFF1], 0		; IFF1 = 0
	xbclr [%CPU+IFF2], 0		; IFF2 = 0
	ret.d
	sub %CYCLE, CYCLE_DI		; *delay*

z80cpu_EI:
	xbset [%CPU+IFF1], 0		; IFF1 = 1
	xbset [%CPU+IFF2], 0		; IFF2 = 1
	ret.d
	sub %CYCLE, CYCLE_EI		; *delay*

z80cpu_IM_0:
	xld.w  %t0, 0			; IM = 0
	xld.b [%CPU+IM], %t0
	ret.d
	sub %CYCLE, CYCLE_IM_0		; *delay*

z80cpu_IM_1:
	xld.w  %t0, 1			; IM = 1
	xld.b [%CPU+IM], %t0
	ret.d
	sub %CYCLE, CYCLE_IM_1		; *delay*

z80cpu_IM_2:
	xld.w  %t0, 2			; IM = 2
	xld.b [%CPU+IM], %t0
	ret.d
	sub %CYCLE, CYCLE_IM_2		; *delay*

;****************************************************************************
;	16-Bit Arithmetic Group
;****************************************************************************

	.global z80cpu_ADD_HL_BC
	.global z80cpu_ADD_HL_DE
	.global z80cpu_ADD_HL_HL
	.global z80cpu_ADD_HL_SP
	.global z80cpu_ADD_IX_BC
	.global z80cpu_ADD_IX_DE
	.global z80cpu_ADD_IX_IX
	.global z80cpu_ADD_IX_SP
	.global z80cpu_ADD_IY_BC
	.global z80cpu_ADD_IY_DE
	.global z80cpu_ADD_IY_IY
	.global z80cpu_ADD_IY_SP

	.global z80cpu_ADC_HL_BC
	.global z80cpu_ADC_HL_DE
	.global z80cpu_ADC_HL_HL
	.global z80cpu_ADC_HL_SP

	.global z80cpu_SBC_HL_BC
	.global z80cpu_SBC_HL_DE
	.global z80cpu_SBC_HL_HL
	.global z80cpu_SBC_HL_SP

	.global z80cpu_INC_BC
	.global z80cpu_INC_DE
	.global z80cpu_INC_HL
	.global z80cpu_INC_SP
	.global z80cpu_INC_IX
	.global z80cpu_INC_IY

	.global z80cpu_DEC_BC
	.global z80cpu_DEC_DE
	.global z80cpu_DEC_HL
	.global z80cpu_DEC_SP
	.global z80cpu_DEC_IX
	.global z80cpu_DEC_IY

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

#macro ADD_rr_ss $1, $2, $3
	xld.uh %a0, [%CPU+$2]		; %a0 = rr
	xld.uh %a1, [%CPU+$3]		; %a1 = ss
	xcall z80cpu_add16
	xld.h [%CPU+$2], %a0		; %rr = rr+ss
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_ADD_HL_BC:
	ADD_rr_ss CYCLE_ADD_HL_BC, HL, BC
z80cpu_ADD_HL_DE:
	ADD_rr_ss CYCLE_ADD_HL_DE, HL, DE
z80cpu_ADD_HL_HL:
	ADD_rr_ss CYCLE_ADD_HL_HL, HL, HL
z80cpu_ADD_HL_SP:
	ADD_rr_ss CYCLE_ADD_HL_SP, HL, SP
z80cpu_ADD_IX_BC:
	ADD_rr_ss CYCLE_ADD_IX_BC, IX, BC
z80cpu_ADD_IX_DE:
	ADD_rr_ss CYCLE_ADD_IX_DE, IX, DE
z80cpu_ADD_IX_IX:
	ADD_rr_ss CYCLE_ADD_IX_IX, IX, IX
z80cpu_ADD_IX_SP:
	ADD_rr_ss CYCLE_ADD_IX_SP, IX, SP
z80cpu_ADD_IY_BC:
	ADD_rr_ss CYCLE_ADD_IY_BC, IY, BC
z80cpu_ADD_IY_DE:
	ADD_rr_ss CYCLE_ADD_IY_DE, IY, DE
z80cpu_ADD_IY_IY:
	ADD_rr_ss CYCLE_ADD_IY_IY, IY, IY
z80cpu_ADD_IY_SP:
	ADD_rr_ss CYCLE_ADD_IY_SP, IY, SP

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

#macro ADC_rr_ss $1, $2, $3
	xld.uh %a0, [%CPU+$2]		; %a0 = rr
	xld.uh %a1, [%CPU+$3]		; %a1 = ss
	xcall z80cpu_adc16
	xld.h [%CPU+$2], %a0		; rr = rr+ss+F(C)
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_ADC_HL_BC:
	ADC_rr_ss CYCLE_ADC_HL_BC, HL, BC
z80cpu_ADC_HL_DE:
	ADC_rr_ss CYCLE_ADC_HL_DE, HL, DE
z80cpu_ADC_HL_HL:
	ADC_rr_ss CYCLE_ADC_HL_HL, HL, HL
z80cpu_ADC_HL_SP:
	ADC_rr_ss CYCLE_ADC_HL_SP, HL, SP

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

#macro SBC_rr_ss $1, $2, $3
	xld.uh %a0, [%CPU+$2]		; %a0 = rr
	xld.uh %a1, [%CPU+$3]		; %a1 = ss
	xcall z80cpu_sbc16
	xld.h [%CPU+$2], %a0		; rr = rr-ss-F(C)
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_SBC_HL_BC:
	SBC_rr_ss CYCLE_SBC_HL_BC, HL, BC
z80cpu_SBC_HL_DE:
	SBC_rr_ss CYCLE_SBC_HL_DE, HL, DE
z80cpu_SBC_HL_HL:
	SBC_rr_ss CYCLE_SBC_HL_HL, HL, HL
z80cpu_SBC_HL_SP:
	SBC_rr_ss CYCLE_SBC_HL_SP, HL, SP

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

;
;	Condition Bits Affected: None
;
#macro INC_rr $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	xadd   %t0, %t0, 1		; %t0 = rr+1
	xld.h [%CPU+$2], %t0		; rr = rr+1
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_INC_BC:
	INC_rr CYCLE_INC_BC, BC
z80cpu_INC_DE:
	INC_rr CYCLE_INC_DE, DE
z80cpu_INC_HL:
	INC_rr CYCLE_INC_HL, HL
z80cpu_INC_SP:
	INC_rr CYCLE_INC_SP, SP
z80cpu_INC_IX:
	INC_rr CYCLE_INC_IX, IX
z80cpu_INC_IY:
	INC_rr CYCLE_INC_IY, IY

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

;
;	Condition Bits Affected: None
;
#macro DEC_rr $1, $2
	xld.uh %t0, [%CPU+$2]		; %t0 = rr
	xsub   %t0, %t0, 1		; %t0 = rr-1
	xld.h [%CPU+$2], %t0		; rr = rr-1
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_DEC_BC:
	DEC_rr CYCLE_DEC_BC, BC
z80cpu_DEC_DE:
	DEC_rr CYCLE_DEC_DE, DE
z80cpu_DEC_HL:
	DEC_rr CYCLE_DEC_HL, HL
z80cpu_DEC_SP:
	DEC_rr CYCLE_DEC_SP, SP
z80cpu_DEC_IX:
	DEC_rr CYCLE_DEC_IX, IX
z80cpu_DEC_IY:
	DEC_rr CYCLE_DEC_IY, IY

;****************************************************************************
;	Rotate and Shift Group
;****************************************************************************

	.global z80cpu_RLA
	.global z80cpu_RLCA
	.global z80cpu_RRA
	.global z80cpu_RRCA

	.global z80cpu_RL_A
	.global z80cpu_RL_B
	.global z80cpu_RL_C
	.global z80cpu_RL_D
	.global z80cpu_RL_E
	.global z80cpu_RL_H
	.global z80cpu_RL_L
	.global z80cpu_RL_IHLI
	.global z80cpu_RL_IaddrI

	.global z80cpu_RLC_A
	.global z80cpu_RLC_B
	.global z80cpu_RLC_C
	.global z80cpu_RLC_D
	.global z80cpu_RLC_E
	.global z80cpu_RLC_H
	.global z80cpu_RLC_L
	.global z80cpu_RLC_IHLI
	.global z80cpu_RLC_IaddrI

	.global z80cpu_RR_A
	.global z80cpu_RR_B
	.global z80cpu_RR_C
	.global z80cpu_RR_D
	.global z80cpu_RR_E
	.global z80cpu_RR_H
	.global z80cpu_RR_L
	.global z80cpu_RR_IHLI
	.global z80cpu_RR_IaddrI

	.global z80cpu_RRC_A
	.global z80cpu_RRC_B
	.global z80cpu_RRC_C
	.global z80cpu_RRC_D
	.global z80cpu_RRC_E
	.global z80cpu_RRC_H
	.global z80cpu_RRC_L
	.global z80cpu_RRC_IHLI
	.global z80cpu_RRC_IaddrI

	.global z80cpu_SLA_A
	.global z80cpu_SLA_B
	.global z80cpu_SLA_C
	.global z80cpu_SLA_D
	.global z80cpu_SLA_E
	.global z80cpu_SLA_H
	.global z80cpu_SLA_L
	.global z80cpu_SLA_IHLI
	.global z80cpu_SLA_IaddrI

	.global z80cpu_SRA_A
	.global z80cpu_SRA_B
	.global z80cpu_SRA_C
	.global z80cpu_SRA_D
	.global z80cpu_SRA_E
	.global z80cpu_SRA_H
	.global z80cpu_SRA_L
	.global z80cpu_SRA_IHLI
	.global z80cpu_SRA_IaddrI

	.global z80cpu_SRL_A
	.global z80cpu_SRL_B
	.global z80cpu_SRL_C
	.global z80cpu_SRL_D
	.global z80cpu_SRL_E
	.global z80cpu_SRL_H
	.global z80cpu_SRL_L
	.global z80cpu_SRL_IHLI
	.global z80cpu_SRL_IaddrI

	.global z80cpu_RLD
	.global z80cpu_RRD

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

;
;	S	is not affected
;	Z	is not affected
;	H	is reset
;	P/V	is not affected
;	N	is reset
;	C	is data from bit 7 of Accumulator
;
; [note]
;	* "RL A"とはフラグ変化が異なることに注意してください。
;
z80cpu_RLA:
	ld.w  %t0, %A			; %t0 = 0:AAAAAAAA
	xsll  %A, 1			; %A  = A:AAAAAAA0
	xand  %t1, %F, CF		; %t1 = 0:0000C000
	xsrl  %t1, 3-0			; %t1 = 0:0000000C
	or    %A, %t1			; %A  = A:AAAAAAAC
	ld.ub %A, %A			; %A  = 0:AAAAAAAC
	;
	xand  %F, %F, PF|ZF|SF		; F   = F(00000PZS)
	xsrl  %t0, 7-3			; %t0 =   0000AAAA
	xand  %t0, %t0, CF		; %t0 =   0000A000
	or    %F, %t0			; %F  = F(0000CPZS)
	ret.d
	sub %CYCLE, CYCLE_RLA		; *delay*

;
;	S	is not affected
;	Z	is not affected
;	H	is reset
;	P/V	is not affected
;	N	is reset
;	C	is data from bit 7 of Accumulator
;
; [note]
;	* "RLC A"とはフラグ変化が異なることに注意してください。
;
z80cpu_RLCA:
	ld.w  %t0, %A			; %t0 = 0:AAAAAAAA
	ld.w  %t1, %A			; %t1 = 0:AAAAAAAA
	xsll  %A, 1			; %A  = A:AAAAAAA0
	xsrl  %t1, 7			; %t1 = 0:0000000A
	or    %A, %t1			; %A  = A:AAAAAAAA
	ld.ub %A, %A			; %A  = 0:AAAAAAAA
	;
	xand  %F, %F, PF|ZF|SF		; F   = F(00000PZS)
	xsrl  %t0, 7-3			; %t0 =   0000AAAA
	xand  %t0, %t0, CF		; %t0 =   0000A000
	or    %F, %t0			; %F  = F(0000CPZS)
	ret.d
	sub %CYCLE, CYCLE_RLCA		; *delay*

;
;	S	is not affected
;	Z	is not affected
;	H	is reset
;	P/V	is not affected
;	N	is reset
;	C	is data from bit 0 of Accumulator
;
; [note]
;	* "RR A"とはフラグ変化が異なることに注意してください。
;
z80cpu_RRA:
	ld.w %t0, %A			; %t0 = 0:AAAAAAAA
	xsrl %A, 1			; %A  = 0:0AAAAAAA
	xand %t1, %F, CF		; %t1 = 0:0000C000
	xsll %t1, 7-3			; %t1 = 0:C0000000
	or   %A, %t1			; %t1 = 0:CAAAAAAA
	;
	xand %F, %F, PF|ZF|SF		; %F  = F(00000PZS)
	xsll %t0, 3-0			; %F  = A:AAAAA000
	xand %t0, %t0, CF		; %F  = 0:0000A000
	or   %F, %t0			; %F  = F(0000CPZS)
	ret.d
	sub %CYCLE, CYCLE_RRA		; *delay*

;
;	S	is not affected
;	Z	is not affected
;	H	is reset
;	P/V	is not affected
;	N	is reset
;	C	is data from bit 0 of Accumulator
;
; [note]
;	* "RRC A"とはフラグ変化が異なることに注意してください。
;
z80cpu_RRCA:
	ld.w  %t0, %A			; %t0 = 0:AAAAAAAA
	ld.w  %t1, %A			; %t1 = 0:AAAAAAAA
	xsrl  %A, 1			; %A  = 0:0AAAAAAA
	xsll  %t1, 7			; %t1 = A:A0000000
	or    %A, %t1			; %A  = A:AAAAAAAA
	ld.ub %A, %A			; %A  = 0:AAAAAAAA
	;
	xand  %F, %F, PF|ZF|SF		; %F  = F(00000PZS)
	xsll  %t0, 3-0			; %F  = A:AAAAA000
	xand  %t0, %t0, CF		; %F  = 0:0000A000
	or    %F, %t0			; %F  = F(0000CPZS)
	ret.d
	sub %CYCLE, CYCLE_RRCA		; *delay*

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

z80cpu_RL_A:
	xcall.d z80cpu_rl
	ld.w %a0, %A			; %a0 = A *delay*
	ld.w %A, %a0			; %A = RL A
	ret.d
	sub %CYCLE, CYCLE_RL_A		; *delay*

#macro RL_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xcall z80cpu_rl
	xld.b [%CPU+$2], %a0		; r = RL r
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_RL_B:
	RL_r CYCLE_RL_B, B
z80cpu_RL_C:
	RL_r CYCLE_RL_C, C
z80cpu_RL_D:
	RL_r CYCLE_RL_D, D
z80cpu_RL_E:
	RL_r CYCLE_RL_E, E
z80cpu_RL_H:
	RL_r CYCLE_RL_H, H
z80cpu_RL_L:
	RL_r CYCLE_RL_L, L

z80cpu_RL_IHLI:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	add    %s0, %MEM		; %s0 = mem+HL
	ld.ub  %a0, [%s0]		; %a0 = [mem+HL]
	xcall z80cpu_rl
	ld.b  [%s0], %a0		; [mem+HL] = RL [mem+HL]
	ret.d
	sub %CYCLE, CYCLE_RL_IHLI	; *delay*

z80cpu_RL_IaddrI:
	ld.ub %a0, [%s0]		; %a0 = [addr]
	xcall z80cpu_rl
	ld.b [%s0], %a0			; [addr] = RL [addr]
	ret.d
	sub %CYCLE, CYCLE_RL_IaddrI	; *delay*

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

z80cpu_RLC_A:
	xcall.d z80cpu_rlc
	ld.w %a0, %A			; %a0 = A *delay*
	ld.w %A, %a0			; %A = RLC A
	ret.d
	sub %CYCLE, CYCLE_RLC_A	; *delay*

#macro RLC_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xcall z80cpu_rlc
	xld.b [%CPU+$2], %a0		; r = RLC r
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_RLC_B:
	RLC_r CYCLE_RLC_B, B
z80cpu_RLC_C:
	RLC_r CYCLE_RLC_C, C
z80cpu_RLC_D:
	RLC_r CYCLE_RLC_D, D
z80cpu_RLC_E:
	RLC_r CYCLE_RLC_E, E
z80cpu_RLC_H:
	RLC_r CYCLE_RLC_H, H
z80cpu_RLC_L:
	RLC_r CYCLE_RLC_L, L

z80cpu_RLC_IHLI:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	add    %s0, %MEM		; %s0 = mem+HL
	ld.ub  %a0, [%s0]		; %a0 = [mem+HL]
	xcall z80cpu_rlc
	ld.b  [%s0], %a0		; [mem+HL] = RLC [mem+HL]
	ret.d
	sub %CYCLE, CYCLE_RLC_IHLI	; *delay*

z80cpu_RLC_IaddrI:
	ld.ub %a0, [%s0]		; %a0 = [addr]
	xcall z80cpu_rlc
	ld.b [%s0], %a0			; [addr] = RLC [addr]
	ret.d
	sub %CYCLE, CYCLE_RLC_IaddrI	; *delay*

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

z80cpu_RR_A:
	xcall.d z80cpu_rr
	ld.w %a0, %A			; %a0 = A *delay*
	ld.w %A, %a0			; %A = RR A
	ret.d
	sub %CYCLE, CYCLE_RR_A		; *delay*

#macro RR_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xcall z80cpu_rr
	xld.b [%CPU+$2], %a0		; r = RR r
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_RR_B:
	RR_r CYCLE_RR_B, B
z80cpu_RR_C:
	RR_r CYCLE_RR_C, C
z80cpu_RR_D:
	RR_r CYCLE_RR_D, D
z80cpu_RR_E:
	RR_r CYCLE_RR_E, E
z80cpu_RR_H:
	RR_r CYCLE_RR_H, H
z80cpu_RR_L:
	RR_r CYCLE_RR_L, L

z80cpu_RR_IHLI:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	add    %s0, %MEM		; %s0 = mem+HL
	ld.ub  %a0, [%s0]		; %a0 = [mem+HL]
	xcall z80cpu_rr
	ld.b  [%s0], %a0		; [mem+HL] = RR [mem+HL]
	ret.d
	sub %CYCLE, CYCLE_RR_IHLI	; *delay*

z80cpu_RR_IaddrI:
	ld.ub %a0, [%s0]		; %a0 = [addr]
	xcall z80cpu_rr
	ld.b [%s0], %a0			; [addr] = RR [addr]
	ret.d
	sub %CYCLE, CYCLE_RR_IaddrI	; *delay*

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

z80cpu_RRC_A:
	xcall.d z80cpu_rrc
	ld.w %a0, %A			; %a0 = A *delay*
	ld.w %A, %a0			; %A = RRC A
	ret.d
	sub %CYCLE, CYCLE_RRC_A	; *delay*

#macro RRC_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xcall z80cpu_rrc
	xld.b [%CPU+$2], %a0		; r = RRC r
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_RRC_B:
	RRC_r CYCLE_RRC_B, B
z80cpu_RRC_C:
	RRC_r CYCLE_RRC_C, C
z80cpu_RRC_D:
	RRC_r CYCLE_RRC_D, D
z80cpu_RRC_E:
	RRC_r CYCLE_RRC_E, E
z80cpu_RRC_H:
	RRC_r CYCLE_RRC_H, H
z80cpu_RRC_L:
	RRC_r CYCLE_RRC_L, L

z80cpu_RRC_IHLI:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	add    %s0, %MEM		; %s0 = mem+HL
	ld.ub  %a0, [%s0]		; %a0 = [mem+HL]
	xcall z80cpu_rrc
	ld.b  [%s0], %a0		; [mem+HL] = RRC [mem+HL]
	ret.d
	sub %CYCLE, CYCLE_RRC_IHLI	; *delay*

z80cpu_RRC_IaddrI:
	ld.ub %a0, [%s0]		; %a0 = [addr]
	xcall z80cpu_rrc
	ld.b [%s0], %a0			; [addr] = RRC [addr]
	ret.d
	sub %CYCLE, CYCLE_RRC_IaddrI	; *delay*

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

z80cpu_SLA_A:
	xcall.d z80cpu_sla
	ld.w %a0, %A			; %a0 = A *delay*
	ld.w %A, %a0			; %A = SLA A
	ret.d
	sub %CYCLE, CYCLE_SLA_A		; *delay*

#macro SLA_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xcall z80cpu_sla
	xld.b [%CPU+$2], %a0		; r = SLA r
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_SLA_B:
	SLA_r CYCLE_SLA_B, B
z80cpu_SLA_C:
	SLA_r CYCLE_SLA_C, C
z80cpu_SLA_D:
	SLA_r CYCLE_SLA_D, D
z80cpu_SLA_E:
	SLA_r CYCLE_SLA_E, E
z80cpu_SLA_H:
	SLA_r CYCLE_SLA_H, H
z80cpu_SLA_L:
	SLA_r CYCLE_SLA_L, L

z80cpu_SLA_IHLI:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	add    %s0, %MEM		; %s0 = mem+HL
	ld.ub  %a0, [%s0]		; %a0 = [mem+HL]
	xcall z80cpu_sla
	ld.b  [%s0], %a0		; [mem+HL] = SLA [mem+HL]
	ret.d
	sub %CYCLE, CYCLE_SLA_IHLI	; *delay*

z80cpu_SLA_IaddrI:
	ld.ub %a0, [%s0]		; %a0 = [addr]
	xcall z80cpu_sla
	ld.b [%s0], %a0			; [addr] = SLA [addr]
	ret.d
	sub %CYCLE, CYCLE_SLA_IaddrI	; *delay*

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

z80cpu_SRA_A:
	xcall.d z80cpu_sra
	ld.w %a0, %A			; %a0 = A *delay*
	ld.w %A, %a0			; %a0 = SRA A
	ret.d
	sub %CYCLE, CYCLE_SRA_A		; *delay*

#macro SRA_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = [addr]
	xcall z80cpu_sra
	xld.b [%CPU+$2], %a0		; [addr] = SRA [mem+HL]
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_SRA_B:
	SRA_r CYCLE_SRA_B, B
z80cpu_SRA_C:
	SRA_r CYCLE_SRA_C, C
z80cpu_SRA_D:
	SRA_r CYCLE_SRA_D, D
z80cpu_SRA_E:
	SRA_r CYCLE_SRA_E, E
z80cpu_SRA_H:
	SRA_r CYCLE_SRA_H, H
z80cpu_SRA_L:
	SRA_r CYCLE_SRA_L, L

z80cpu_SRA_IHLI:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	add    %s0, %MEM		; %s0 = mem+HL
	ld.ub  %a0, [%s0]		; %a0 = [mem+HL]
	xcall z80cpu_sra
	ld.b  [%s0], %a0		; [mem+HL] = SRA [mem+HL]
	ret.d
	sub %CYCLE, CYCLE_SRA_IHLI	; *delay*

z80cpu_SRA_IaddrI:
	ld.ub %a0, [%s0]		; %a0 = [addr]
	xcall z80cpu_sra
	ld.b [%s0], %a0			; [addr] = SRA [addr]
	ret.d
	sub %CYCLE, CYCLE_SRA_IaddrI	; *delay*

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

z80cpu_SRL_A:
	xcall.d z80cpu_srl
	ld.w %a0, %A			; %a0 = A *delay*
	ld.w %A, %a0			; %A = SRL A
	ret.d
	sub %CYCLE, CYCLE_SRL_A		; *delay*

#macro SRL_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xcall z80cpu_srl
	xld.b [%CPU+$2], %a0		; r = SRL r
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_SRL_B:
	SRL_r CYCLE_SRL_B, B
z80cpu_SRL_C:
	SRL_r CYCLE_SRL_C, C
z80cpu_SRL_D:
	SRL_r CYCLE_SRL_D, D
z80cpu_SRL_E:
	SRL_r CYCLE_SRL_E, E
z80cpu_SRL_H:
	SRL_r CYCLE_SRL_H, H
z80cpu_SRL_L:
	SRL_r CYCLE_SRL_L, L

z80cpu_SRL_IHLI:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	add    %s0, %MEM		; %s0 = mem+HL
	ld.ub  %a0, [%s0]		; %a0 = [mem+HL]
	xcall z80cpu_srl
	ld.b  [%s0], %a0		; [mem+HL] = SRL [mem+HL]
	ret.d
	sub %CYCLE, CYCLE_SRL_IHLI	; *delay*

z80cpu_SRL_IaddrI:
	ld.ub %a0, [%s0]		; %a0 = [addr]
	xcall z80cpu_srl
	ld.b [%s0], %a0			; [addr] = SRL [addr]
	ret.d
	sub %CYCLE, CYCLE_SRL_IaddrI	; *delay*

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

;
; [note]
;	* 遅くても構わないので、C言語版を呼び出しています。
;	  いずれ、アセンブラ化する予定です。
;
z80cpu_RLD:
	xcall z80cpu_leave		; 実行コンテキストを書き戻します。
	xcall z80cpu_rld
	xjp.d z80cpu_enter		; 実行コンテキストを取り出します。
	sub %CYCLE, CYCLE_RLD		; *delay*

;
; [note]
;	* 遅くても構わないので、C言語版を呼び出しています。
;	  いずれ、アセンブラ化する予定です。
;
z80cpu_RRD:
	xcall z80cpu_leave		; 実行コンテキストを書き戻します。
	xcall z80cpu_rrd
	xjp.d z80cpu_enter		; 実行コンテキストを取り出します。
	sub %CYCLE, CYCLE_RRD		; *delay*

;****************************************************************************
;	Bit Set, Reset, and Test Group
;****************************************************************************

	.global z80cpu_BIT_0_A
	.global z80cpu_BIT_0_B
	.global z80cpu_BIT_0_C
	.global z80cpu_BIT_0_D
	.global z80cpu_BIT_0_E
	.global z80cpu_BIT_0_H
	.global z80cpu_BIT_0_L
	.global z80cpu_BIT_0_IHLI
	.global z80cpu_BIT_0_IaddrI
	.global z80cpu_BIT_1_A
	.global z80cpu_BIT_1_B
	.global z80cpu_BIT_1_C
	.global z80cpu_BIT_1_D
	.global z80cpu_BIT_1_E
	.global z80cpu_BIT_1_H
	.global z80cpu_BIT_1_L
	.global z80cpu_BIT_1_IHLI
	.global z80cpu_BIT_1_IaddrI
	.global z80cpu_BIT_2_A
	.global z80cpu_BIT_2_B
	.global z80cpu_BIT_2_C
	.global z80cpu_BIT_2_D
	.global z80cpu_BIT_2_E
	.global z80cpu_BIT_2_H
	.global z80cpu_BIT_2_L
	.global z80cpu_BIT_2_IHLI
	.global z80cpu_BIT_2_IaddrI
	.global z80cpu_BIT_3_A
	.global z80cpu_BIT_3_B
	.global z80cpu_BIT_3_C
	.global z80cpu_BIT_3_D
	.global z80cpu_BIT_3_E
	.global z80cpu_BIT_3_H
	.global z80cpu_BIT_3_L
	.global z80cpu_BIT_3_IHLI
	.global z80cpu_BIT_3_IaddrI
	.global z80cpu_BIT_4_A
	.global z80cpu_BIT_4_B
	.global z80cpu_BIT_4_C
	.global z80cpu_BIT_4_D
	.global z80cpu_BIT_4_E
	.global z80cpu_BIT_4_H
	.global z80cpu_BIT_4_L
	.global z80cpu_BIT_4_IHLI
	.global z80cpu_BIT_4_IaddrI
	.global z80cpu_BIT_5_A
	.global z80cpu_BIT_5_B
	.global z80cpu_BIT_5_C
	.global z80cpu_BIT_5_D
	.global z80cpu_BIT_5_E
	.global z80cpu_BIT_5_H
	.global z80cpu_BIT_5_L
	.global z80cpu_BIT_5_IHLI
	.global z80cpu_BIT_5_IaddrI
	.global z80cpu_BIT_6_A
	.global z80cpu_BIT_6_B
	.global z80cpu_BIT_6_C
	.global z80cpu_BIT_6_D
	.global z80cpu_BIT_6_E
	.global z80cpu_BIT_6_H
	.global z80cpu_BIT_6_L
	.global z80cpu_BIT_6_IHLI
	.global z80cpu_BIT_6_IaddrI
	.global z80cpu_BIT_7_A
	.global z80cpu_BIT_7_B
	.global z80cpu_BIT_7_C
	.global z80cpu_BIT_7_D
	.global z80cpu_BIT_7_E
	.global z80cpu_BIT_7_H
	.global z80cpu_BIT_7_L
	.global z80cpu_BIT_7_IHLI
	.global z80cpu_BIT_7_IaddrI

	.global z80cpu_SET_0_A
	.global z80cpu_SET_0_B
	.global z80cpu_SET_0_C
	.global z80cpu_SET_0_D
	.global z80cpu_SET_0_E
	.global z80cpu_SET_0_H
	.global z80cpu_SET_0_L
	.global z80cpu_SET_0_IHLI
	.global z80cpu_SET_0_IaddrI
	.global z80cpu_SET_1_A
	.global z80cpu_SET_1_B
	.global z80cpu_SET_1_C
	.global z80cpu_SET_1_D
	.global z80cpu_SET_1_E
	.global z80cpu_SET_1_H
	.global z80cpu_SET_1_L
	.global z80cpu_SET_1_IHLI
	.global z80cpu_SET_1_IaddrI
	.global z80cpu_SET_2_A
	.global z80cpu_SET_2_B
	.global z80cpu_SET_2_C
	.global z80cpu_SET_2_D
	.global z80cpu_SET_2_E
	.global z80cpu_SET_2_H
	.global z80cpu_SET_2_L
	.global z80cpu_SET_2_IHLI
	.global z80cpu_SET_2_IaddrI
	.global z80cpu_SET_3_A
	.global z80cpu_SET_3_B
	.global z80cpu_SET_3_C
	.global z80cpu_SET_3_D
	.global z80cpu_SET_3_E
	.global z80cpu_SET_3_H
	.global z80cpu_SET_3_L
	.global z80cpu_SET_3_IHLI
	.global z80cpu_SET_3_IaddrI
	.global z80cpu_SET_4_A
	.global z80cpu_SET_4_B
	.global z80cpu_SET_4_C
	.global z80cpu_SET_4_D
	.global z80cpu_SET_4_E
	.global z80cpu_SET_4_H
	.global z80cpu_SET_4_L
	.global z80cpu_SET_4_IHLI
	.global z80cpu_SET_4_IaddrI
	.global z80cpu_SET_5_A
	.global z80cpu_SET_5_B
	.global z80cpu_SET_5_C
	.global z80cpu_SET_5_D
	.global z80cpu_SET_5_E
	.global z80cpu_SET_5_H
	.global z80cpu_SET_5_L
	.global z80cpu_SET_5_IHLI
	.global z80cpu_SET_5_IaddrI
	.global z80cpu_SET_6_A
	.global z80cpu_SET_6_B
	.global z80cpu_SET_6_C
	.global z80cpu_SET_6_D
	.global z80cpu_SET_6_E
	.global z80cpu_SET_6_H
	.global z80cpu_SET_6_L
	.global z80cpu_SET_6_IHLI
	.global z80cpu_SET_6_IaddrI
	.global z80cpu_SET_7_A
	.global z80cpu_SET_7_B
	.global z80cpu_SET_7_C
	.global z80cpu_SET_7_D
	.global z80cpu_SET_7_E
	.global z80cpu_SET_7_H
	.global z80cpu_SET_7_L
	.global z80cpu_SET_7_IHLI
	.global z80cpu_SET_7_IaddrI

	.global z80cpu_RES_0_A
	.global z80cpu_RES_0_B
	.global z80cpu_RES_0_C
	.global z80cpu_RES_0_D
	.global z80cpu_RES_0_E
	.global z80cpu_RES_0_H
	.global z80cpu_RES_0_L
	.global z80cpu_RES_0_IHLI
	.global z80cpu_RES_0_IaddrI
	.global z80cpu_RES_1_A
	.global z80cpu_RES_1_B
	.global z80cpu_RES_1_C
	.global z80cpu_RES_1_D
	.global z80cpu_RES_1_E
	.global z80cpu_RES_1_H
	.global z80cpu_RES_1_L
	.global z80cpu_RES_1_IHLI
	.global z80cpu_RES_1_IaddrI
	.global z80cpu_RES_2_A
	.global z80cpu_RES_2_B
	.global z80cpu_RES_2_C
	.global z80cpu_RES_2_D
	.global z80cpu_RES_2_E
	.global z80cpu_RES_2_H
	.global z80cpu_RES_2_L
	.global z80cpu_RES_2_IHLI
	.global z80cpu_RES_2_IaddrI
	.global z80cpu_RES_3_A
	.global z80cpu_RES_3_B
	.global z80cpu_RES_3_C
	.global z80cpu_RES_3_D
	.global z80cpu_RES_3_E
	.global z80cpu_RES_3_H
	.global z80cpu_RES_3_L
	.global z80cpu_RES_3_IHLI
	.global z80cpu_RES_3_IaddrI
	.global z80cpu_RES_4_A
	.global z80cpu_RES_4_B
	.global z80cpu_RES_4_C
	.global z80cpu_RES_4_D
	.global z80cpu_RES_4_E
	.global z80cpu_RES_4_H
	.global z80cpu_RES_4_L
	.global z80cpu_RES_4_IHLI
	.global z80cpu_RES_4_IaddrI
	.global z80cpu_RES_5_A
	.global z80cpu_RES_5_B
	.global z80cpu_RES_5_C
	.global z80cpu_RES_5_D
	.global z80cpu_RES_5_E
	.global z80cpu_RES_5_H
	.global z80cpu_RES_5_L
	.global z80cpu_RES_5_IHLI
	.global z80cpu_RES_5_IaddrI
	.global z80cpu_RES_6_A
	.global z80cpu_RES_6_B
	.global z80cpu_RES_6_C
	.global z80cpu_RES_6_D
	.global z80cpu_RES_6_E
	.global z80cpu_RES_6_H
	.global z80cpu_RES_6_L
	.global z80cpu_RES_6_IHLI
	.global z80cpu_RES_6_IaddrI
	.global z80cpu_RES_7_A
	.global z80cpu_RES_7_B
	.global z80cpu_RES_7_C
	.global z80cpu_RES_7_D
	.global z80cpu_RES_7_E
	.global z80cpu_RES_7_H
	.global z80cpu_RES_7_L	
	.global z80cpu_RES_7_IHLI
	.global z80cpu_RES_7_IaddrI

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

#macro BIT_b_A $1, $2
	xld.w %a0, $2			; %a0 = b
	ld.w  %a1, %A			; %a1 = A
	xjp.d z80cpu_bit
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_BIT_0_A:
	BIT_b_A CYCLE_BIT_0_A, 0
z80cpu_BIT_1_A:
	BIT_b_A CYCLE_BIT_1_A, 1
z80cpu_BIT_2_A:
	BIT_b_A CYCLE_BIT_2_A, 2
z80cpu_BIT_3_A:
	BIT_b_A CYCLE_BIT_3_A, 3
z80cpu_BIT_4_A:
	BIT_b_A CYCLE_BIT_4_A, 4
z80cpu_BIT_5_A:
	BIT_b_A CYCLE_BIT_5_A, 5
z80cpu_BIT_6_A:
	BIT_b_A CYCLE_BIT_6_A, 6
z80cpu_BIT_7_A:
	BIT_b_A CYCLE_BIT_7_A, 7

#macro BIT_b_r $1, $2, $3
	xld.w  %a0, $2			; %a0 = b
	xld.ub %a1, [%CPU+$3]		; %a1 = r
	xjp.d z80cpu_bit
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_BIT_0_B:
	BIT_b_r CYCLE_BIT_0_B, 0, B
z80cpu_BIT_1_B:
	BIT_b_r CYCLE_BIT_1_B, 1, B
z80cpu_BIT_2_B:
	BIT_b_r CYCLE_BIT_2_B, 2, B
z80cpu_BIT_3_B:
	BIT_b_r CYCLE_BIT_3_B, 3, B
z80cpu_BIT_4_B:
	BIT_b_r CYCLE_BIT_4_B, 4, B
z80cpu_BIT_5_B:
	BIT_b_r CYCLE_BIT_5_B, 5, B
z80cpu_BIT_6_B:
	BIT_b_r CYCLE_BIT_6_B, 6, B
z80cpu_BIT_7_B:
	BIT_b_r CYCLE_BIT_7_B, 7, B

z80cpu_BIT_0_C:
	BIT_b_r CYCLE_BIT_0_C, 0, C
z80cpu_BIT_1_C:
	BIT_b_r CYCLE_BIT_1_C, 1, C
z80cpu_BIT_2_C:
	BIT_b_r CYCLE_BIT_2_C, 2, C
z80cpu_BIT_3_C:
	BIT_b_r CYCLE_BIT_3_C, 3, C
z80cpu_BIT_4_C:
	BIT_b_r CYCLE_BIT_4_C, 4, C
z80cpu_BIT_5_C:
	BIT_b_r CYCLE_BIT_5_C, 5, C
z80cpu_BIT_6_C:
	BIT_b_r CYCLE_BIT_6_C, 6, C
z80cpu_BIT_7_C:
	BIT_b_r CYCLE_BIT_7_C, 7, C

z80cpu_BIT_0_D:
	BIT_b_r CYCLE_BIT_0_D, 0, D
z80cpu_BIT_1_D:
	BIT_b_r CYCLE_BIT_1_D, 1, D
z80cpu_BIT_2_D:
	BIT_b_r CYCLE_BIT_2_D, 2, D
z80cpu_BIT_3_D:
	BIT_b_r CYCLE_BIT_3_D, 3, D
z80cpu_BIT_4_D:
	BIT_b_r CYCLE_BIT_4_D, 4, D
z80cpu_BIT_5_D:
	BIT_b_r CYCLE_BIT_5_D, 5, D
z80cpu_BIT_6_D:
	BIT_b_r CYCLE_BIT_6_D, 6, D
z80cpu_BIT_7_D:
	BIT_b_r CYCLE_BIT_7_D, 7, D

z80cpu_BIT_0_E:
	BIT_b_r CYCLE_BIT_0_E, 0, E
z80cpu_BIT_1_E:
	BIT_b_r CYCLE_BIT_1_E, 1, E
z80cpu_BIT_2_E:
	BIT_b_r CYCLE_BIT_2_E, 2, E
z80cpu_BIT_3_E:
	BIT_b_r CYCLE_BIT_3_E, 3, E
z80cpu_BIT_4_E:
	BIT_b_r CYCLE_BIT_4_E, 4, E
z80cpu_BIT_5_E:
	BIT_b_r CYCLE_BIT_5_E, 5, E
z80cpu_BIT_6_E:
	BIT_b_r CYCLE_BIT_6_E, 6, E
z80cpu_BIT_7_E:
	BIT_b_r CYCLE_BIT_7_E, 7, E

z80cpu_BIT_0_H:
	BIT_b_r CYCLE_BIT_0_H, 0, H
z80cpu_BIT_1_H:
	BIT_b_r CYCLE_BIT_1_H, 1, H
z80cpu_BIT_2_H:
	BIT_b_r CYCLE_BIT_2_H, 2, H
z80cpu_BIT_3_H:
	BIT_b_r CYCLE_BIT_3_H, 3, H
z80cpu_BIT_4_H:
	BIT_b_r CYCLE_BIT_4_H, 4, H
z80cpu_BIT_5_H:
	BIT_b_r CYCLE_BIT_5_H, 5, H
z80cpu_BIT_6_H:
	BIT_b_r CYCLE_BIT_6_H, 6, H
z80cpu_BIT_7_H:
	BIT_b_r CYCLE_BIT_7_H, 7, H

z80cpu_BIT_0_L:
	BIT_b_r CYCLE_BIT_0_L, 0, L
z80cpu_BIT_1_L:
	BIT_b_r CYCLE_BIT_1_L, 1, L
z80cpu_BIT_2_L:
	BIT_b_r CYCLE_BIT_2_L, 2, L
z80cpu_BIT_3_L:
	BIT_b_r CYCLE_BIT_3_L, 3, L
z80cpu_BIT_4_L:
	BIT_b_r CYCLE_BIT_4_L, 4, L
z80cpu_BIT_5_L:
	BIT_b_r CYCLE_BIT_5_L, 5, L
z80cpu_BIT_6_L:
	BIT_b_r CYCLE_BIT_6_L, 6, L
z80cpu_BIT_7_L:
	BIT_b_r CYCLE_BIT_7_L, 7, L

#macro BIT_b_IHLI $1, $2
	xld.w  %a0, $2			; %a0 = b
	xld.uh %a1, [%CPU+HL]		; %a1 = HL
	add    %a1, %MEM		; %a1 = mem+HL
	ld.ub  %a1, [%a1]		; %a1 = [mem+HL]
	xjp.d z80cpu_bit
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_BIT_0_IHLI:
	BIT_b_IHLI CYCLE_BIT_0_IHLI, 0
z80cpu_BIT_1_IHLI:
	BIT_b_IHLI CYCLE_BIT_1_IHLI, 1
z80cpu_BIT_2_IHLI:
	BIT_b_IHLI CYCLE_BIT_2_IHLI, 2
z80cpu_BIT_3_IHLI:
	BIT_b_IHLI CYCLE_BIT_3_IHLI, 3
z80cpu_BIT_4_IHLI:
	BIT_b_IHLI CYCLE_BIT_4_IHLI, 4
z80cpu_BIT_5_IHLI:
	BIT_b_IHLI CYCLE_BIT_5_IHLI, 5
z80cpu_BIT_6_IHLI:
	BIT_b_IHLI CYCLE_BIT_6_IHLI, 6
z80cpu_BIT_7_IHLI:
	BIT_b_IHLI CYCLE_BIT_7_IHLI, 7

#macro BIT_b_IaddrI $1, $2
	xld.w %a0, $2			; %a0 = b
	ld.ub %a1, [%s0]		; %a1 = [addr]
	xjp.d z80cpu_bit
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_BIT_0_IaddrI:
	BIT_b_IaddrI CYCLE_BIT_0_IaddrI, 0
z80cpu_BIT_1_IaddrI:
	BIT_b_IaddrI CYCLE_BIT_1_IaddrI, 1
z80cpu_BIT_2_IaddrI:
	BIT_b_IaddrI CYCLE_BIT_2_IaddrI, 2
z80cpu_BIT_3_IaddrI:
	BIT_b_IaddrI CYCLE_BIT_3_IaddrI, 3
z80cpu_BIT_4_IaddrI:
	BIT_b_IaddrI CYCLE_BIT_4_IaddrI, 4
z80cpu_BIT_5_IaddrI:
	BIT_b_IaddrI CYCLE_BIT_5_IaddrI, 5
z80cpu_BIT_6_IaddrI:
	BIT_b_IaddrI CYCLE_BIT_6_IaddrI, 6
z80cpu_BIT_7_IaddrI:
	BIT_b_IaddrI CYCLE_BIT_7_IaddrI, 7

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

#macro SET_b_A $1, $2
	xoor %A, %A, 1<<$2		; %A = A|(1<<b)
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_SET_0_A:
	SET_b_A CYCLE_SET_0_A, 0
z80cpu_SET_1_A:
	SET_b_A CYCLE_SET_1_A, 1
z80cpu_SET_2_A:
	SET_b_A CYCLE_SET_2_A, 2
z80cpu_SET_3_A:
	SET_b_A CYCLE_SET_3_A, 3
z80cpu_SET_4_A:
	SET_b_A CYCLE_SET_4_A, 4
z80cpu_SET_5_A:
	SET_b_A CYCLE_SET_5_A, 5
z80cpu_SET_6_A:
	SET_b_A CYCLE_SET_6_A, 6
z80cpu_SET_7_A:
	SET_b_A CYCLE_SET_7_A, 7

#macro SET_b_r $1, $2, $3
	xbset [%CPU+$3], $2		; r = r|(1<<b)
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_SET_0_B:
	SET_b_r CYCLE_SET_0_B, 0, B
z80cpu_SET_1_B:
	SET_b_r CYCLE_SET_1_B, 1, B
z80cpu_SET_2_B:
	SET_b_r CYCLE_SET_2_B, 2, B
z80cpu_SET_3_B:
	SET_b_r CYCLE_SET_3_B, 3, B
z80cpu_SET_4_B:
	SET_b_r CYCLE_SET_4_B, 4, B
z80cpu_SET_5_B:
	SET_b_r CYCLE_SET_5_B, 5, B
z80cpu_SET_6_B:
	SET_b_r CYCLE_SET_6_B, 6, B
z80cpu_SET_7_B:
	SET_b_r CYCLE_SET_7_B, 7, B

z80cpu_SET_0_C:
	SET_b_r CYCLE_SET_0_C, 0, C
z80cpu_SET_1_C:
	SET_b_r CYCLE_SET_1_C, 1, C
z80cpu_SET_2_C:
	SET_b_r CYCLE_SET_2_C, 2, C
z80cpu_SET_3_C:
	SET_b_r CYCLE_SET_3_C, 3, C
z80cpu_SET_4_C:
	SET_b_r CYCLE_SET_4_C, 4, C
z80cpu_SET_5_C:
	SET_b_r CYCLE_SET_5_C, 5, C
z80cpu_SET_6_C:
	SET_b_r CYCLE_SET_6_C, 6, C
z80cpu_SET_7_C:
	SET_b_r CYCLE_SET_7_C, 7, C

z80cpu_SET_0_D:
	SET_b_r CYCLE_SET_0_D, 0, D
z80cpu_SET_1_D:
	SET_b_r CYCLE_SET_1_D, 1, D
z80cpu_SET_2_D:
	SET_b_r CYCLE_SET_2_D, 2, D
z80cpu_SET_3_D:
	SET_b_r CYCLE_SET_3_D, 3, D
z80cpu_SET_4_D:
	SET_b_r CYCLE_SET_4_D, 4, D
z80cpu_SET_5_D:
	SET_b_r CYCLE_SET_5_D, 5, D
z80cpu_SET_6_D:
	SET_b_r CYCLE_SET_6_D, 6, D
z80cpu_SET_7_D:
	SET_b_r CYCLE_SET_7_D, 7, D

z80cpu_SET_0_E:
	SET_b_r CYCLE_SET_0_E, 0, E
z80cpu_SET_1_E:
	SET_b_r CYCLE_SET_1_E, 1, E
z80cpu_SET_2_E:
	SET_b_r CYCLE_SET_2_E, 2, E
z80cpu_SET_3_E:
	SET_b_r CYCLE_SET_3_E, 3, E
z80cpu_SET_4_E:
	SET_b_r CYCLE_SET_4_E, 4, E
z80cpu_SET_5_E:
	SET_b_r CYCLE_SET_5_E, 5, E
z80cpu_SET_6_E:
	SET_b_r CYCLE_SET_6_E, 6, E
z80cpu_SET_7_E:
	SET_b_r CYCLE_SET_7_E, 7, E

z80cpu_SET_0_H:
	SET_b_r CYCLE_SET_0_H, 0, H
z80cpu_SET_1_H:
	SET_b_r CYCLE_SET_1_H, 1, H
z80cpu_SET_2_H:
	SET_b_r CYCLE_SET_2_H, 2, H
z80cpu_SET_3_H:
	SET_b_r CYCLE_SET_3_H, 3, H
z80cpu_SET_4_H:
	SET_b_r CYCLE_SET_4_H, 4, H
z80cpu_SET_5_H:
	SET_b_r CYCLE_SET_5_H, 5, H
z80cpu_SET_6_H:
	SET_b_r CYCLE_SET_6_H, 6, H
z80cpu_SET_7_H:
	SET_b_r CYCLE_SET_7_H, 7, H

z80cpu_SET_0_L:
	SET_b_r CYCLE_SET_0_L, 0, L
z80cpu_SET_1_L:
	SET_b_r CYCLE_SET_1_L, 1, L
z80cpu_SET_2_L:
	SET_b_r CYCLE_SET_2_L, 2, L
z80cpu_SET_3_L:
	SET_b_r CYCLE_SET_3_L, 3, L
z80cpu_SET_4_L:
	SET_b_r CYCLE_SET_4_L, 4, L
z80cpu_SET_5_L:
	SET_b_r CYCLE_SET_5_L, 5, L
z80cpu_SET_6_L:
	SET_b_r CYCLE_SET_6_L, 6, L
z80cpu_SET_7_L:
	SET_b_r CYCLE_SET_7_L, 7, L

#macro SET_b_IHLI $1, $2
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	bset  [%t0], $2			; [mem+HL] = [mem+HL]|(1<<b)
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_SET_0_IHLI:
	SET_b_IHLI CYCLE_SET_0_IHLI, 0
z80cpu_SET_1_IHLI:
	SET_b_IHLI CYCLE_SET_1_IHLI, 1
z80cpu_SET_2_IHLI:
	SET_b_IHLI CYCLE_SET_2_IHLI, 2
z80cpu_SET_3_IHLI:
	SET_b_IHLI CYCLE_SET_3_IHLI, 3
z80cpu_SET_4_IHLI:
	SET_b_IHLI CYCLE_SET_4_IHLI, 4
z80cpu_SET_5_IHLI:
	SET_b_IHLI CYCLE_SET_5_IHLI, 5
z80cpu_SET_6_IHLI:
	SET_b_IHLI CYCLE_SET_6_IHLI, 6
z80cpu_SET_7_IHLI:
	SET_b_IHLI CYCLE_SET_7_IHLI, 7

#macro SET_b_IaddrI $1, $2
	bset [%s0], $2			; [addr] = [addr]|(1<<b)
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_SET_0_IaddrI:
	SET_b_IaddrI CYCLE_SET_0_IaddrI, 0
z80cpu_SET_1_IaddrI:
	SET_b_IaddrI CYCLE_SET_1_IaddrI, 1
z80cpu_SET_2_IaddrI:
	SET_b_IaddrI CYCLE_SET_2_IaddrI, 2
z80cpu_SET_3_IaddrI:
	SET_b_IaddrI CYCLE_SET_3_IaddrI, 3
z80cpu_SET_4_IaddrI:
	SET_b_IaddrI CYCLE_SET_4_IaddrI, 4
z80cpu_SET_5_IaddrI:
	SET_b_IaddrI CYCLE_SET_5_IaddrI, 5
z80cpu_SET_6_IaddrI:
	SET_b_IaddrI CYCLE_SET_6_IaddrI, 6
z80cpu_SET_7_IaddrI:
	SET_b_IaddrI CYCLE_SET_7_IaddrI, 7

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

#macro RES_b_A $1, $2
	xand %A, %A, ~(1<<$2)		; %A = A&~(1<<b)
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_RES_0_A:
	RES_b_A CYCLE_RES_0_A, 0
z80cpu_RES_1_A:
	RES_b_A CYCLE_RES_1_A, 1
z80cpu_RES_2_A:
	RES_b_A CYCLE_RES_2_A, 2
z80cpu_RES_3_A:
	RES_b_A CYCLE_RES_3_A, 3
z80cpu_RES_4_A:
	RES_b_A CYCLE_RES_4_A, 4
z80cpu_RES_5_A:
	RES_b_A CYCLE_RES_5_A, 5
z80cpu_RES_6_A:
	RES_b_A CYCLE_RES_6_A, 6
z80cpu_RES_7_A:
	RES_b_A CYCLE_RES_7_A, 7

#macro RES_b_r $1, $2, $3
	xbclr [%CPU+$3], $2		; r = r&~(1<<b)
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_RES_0_B:
	RES_b_r CYCLE_RES_0_B, 0, B
z80cpu_RES_1_B:
	RES_b_r CYCLE_RES_1_B, 1, B
z80cpu_RES_2_B:
	RES_b_r CYCLE_RES_2_B, 2, B
z80cpu_RES_3_B:
	RES_b_r CYCLE_RES_3_B, 3, B
z80cpu_RES_4_B:
	RES_b_r CYCLE_RES_4_B, 4, B
z80cpu_RES_5_B:
	RES_b_r CYCLE_RES_5_B, 5, B
z80cpu_RES_6_B:
	RES_b_r CYCLE_RES_6_B, 6, B
z80cpu_RES_7_B:
	RES_b_r CYCLE_RES_7_B, 7, B

z80cpu_RES_0_C:
	RES_b_r CYCLE_RES_0_C, 0, C
z80cpu_RES_1_C:
	RES_b_r CYCLE_RES_1_C, 1, C
z80cpu_RES_2_C:
	RES_b_r CYCLE_RES_2_C, 2, C
z80cpu_RES_3_C:
	RES_b_r CYCLE_RES_3_C, 3, C
z80cpu_RES_4_C:
	RES_b_r CYCLE_RES_4_C, 4, C
z80cpu_RES_5_C:
	RES_b_r CYCLE_RES_5_C, 5, C
z80cpu_RES_6_C:
	RES_b_r CYCLE_RES_6_C, 6, C
z80cpu_RES_7_C:
	RES_b_r CYCLE_RES_7_C, 7, C

z80cpu_RES_0_D:
	RES_b_r CYCLE_RES_0_D, 0, D
z80cpu_RES_1_D:
	RES_b_r CYCLE_RES_1_D, 1, D
z80cpu_RES_2_D:
	RES_b_r CYCLE_RES_2_D, 2, D
z80cpu_RES_3_D:
	RES_b_r CYCLE_RES_3_D, 3, D
z80cpu_RES_4_D:
	RES_b_r CYCLE_RES_4_D, 4, D
z80cpu_RES_5_D:
	RES_b_r CYCLE_RES_5_D, 5, D
z80cpu_RES_6_D:
	RES_b_r CYCLE_RES_6_D, 6, D
z80cpu_RES_7_D:
	RES_b_r CYCLE_RES_7_D, 7, D

z80cpu_RES_0_E:
	RES_b_r CYCLE_RES_0_E, 0, E
z80cpu_RES_1_E:
	RES_b_r CYCLE_RES_1_E, 1, E
z80cpu_RES_2_E:
	RES_b_r CYCLE_RES_2_E, 2, E
z80cpu_RES_3_E:
	RES_b_r CYCLE_RES_3_E, 3, E
z80cpu_RES_4_E:
	RES_b_r CYCLE_RES_4_E, 4, E
z80cpu_RES_5_E:
	RES_b_r CYCLE_RES_5_E, 5, E
z80cpu_RES_6_E:
	RES_b_r CYCLE_RES_6_E, 6, E
z80cpu_RES_7_E:
	RES_b_r CYCLE_RES_7_E, 7, E

z80cpu_RES_0_H:
	RES_b_r CYCLE_RES_0_H, 0, H
z80cpu_RES_1_H:
	RES_b_r CYCLE_RES_1_H, 1, H
z80cpu_RES_2_H:
	RES_b_r CYCLE_RES_2_H, 2, H
z80cpu_RES_3_H:
	RES_b_r CYCLE_RES_3_H, 3, H
z80cpu_RES_4_H:
	RES_b_r CYCLE_RES_4_H, 4, H
z80cpu_RES_5_H:
	RES_b_r CYCLE_RES_5_H, 5, H
z80cpu_RES_6_H:
	RES_b_r CYCLE_RES_6_H, 6, H
z80cpu_RES_7_H:
	RES_b_r CYCLE_RES_7_H, 7, H

z80cpu_RES_0_L:
	RES_b_r CYCLE_RES_0_L, 0, L
z80cpu_RES_1_L:
	RES_b_r CYCLE_RES_1_L, 1, L
z80cpu_RES_2_L:
	RES_b_r CYCLE_RES_2_L, 2, L
z80cpu_RES_3_L:
	RES_b_r CYCLE_RES_3_L, 3, L
z80cpu_RES_4_L:
	RES_b_r CYCLE_RES_4_L, 4, L
z80cpu_RES_5_L:
	RES_b_r CYCLE_RES_5_L, 5, L
z80cpu_RES_6_L:
	RES_b_r CYCLE_RES_6_L, 6, L
z80cpu_RES_7_L:
	RES_b_r CYCLE_RES_7_L, 7, L

#macro RES_b_IHLI $1, $2
	xld.uh %t0, [%CPU+HL]		; %t0 = HL
	add    %t0, %MEM		; %t0 = mem+HL
	bclr  [%t0], $2			; [mem+HL] = [mem+HL]&~(1<<b)
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_RES_0_IHLI:
	RES_b_IHLI CYCLE_RES_0_IHLI, 0
z80cpu_RES_1_IHLI:
	RES_b_IHLI CYCLE_RES_1_IHLI, 1
z80cpu_RES_2_IHLI:
	RES_b_IHLI CYCLE_RES_2_IHLI, 2
z80cpu_RES_3_IHLI:
	RES_b_IHLI CYCLE_RES_3_IHLI, 3
z80cpu_RES_4_IHLI:
	RES_b_IHLI CYCLE_RES_4_IHLI, 4
z80cpu_RES_5_IHLI:
	RES_b_IHLI CYCLE_RES_5_IHLI, 5
z80cpu_RES_6_IHLI:
	RES_b_IHLI CYCLE_RES_6_IHLI, 6
z80cpu_RES_7_IHLI:
	RES_b_IHLI CYCLE_RES_7_IHLI, 7

#macro RES_b_IaddrI $1, $2
	bclr [%s0], $2			; [addr] = [addr]&~(1<<b)
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_RES_0_IaddrI:
	RES_b_IaddrI CYCLE_RES_0_IaddrI, 0
z80cpu_RES_1_IaddrI:
	RES_b_IaddrI CYCLE_RES_1_IaddrI, 1
z80cpu_RES_2_IaddrI:
	RES_b_IaddrI CYCLE_RES_2_IaddrI, 2
z80cpu_RES_3_IaddrI:
	RES_b_IaddrI CYCLE_RES_3_IaddrI, 3
z80cpu_RES_4_IaddrI:
	RES_b_IaddrI CYCLE_RES_4_IaddrI, 4
z80cpu_RES_5_IaddrI:
	RES_b_IaddrI CYCLE_RES_5_IaddrI, 5
z80cpu_RES_6_IaddrI:
	RES_b_IaddrI CYCLE_RES_6_IaddrI, 6
z80cpu_RES_7_IaddrI:
	RES_b_IaddrI CYCLE_RES_7_IaddrI, 7

;****************************************************************************
;	Jump Group
;****************************************************************************

	.global z80cpu_JP_IHLI
	.global z80cpu_JP_IIXI
	.global z80cpu_JP_IIYI

	.global z80cpu_JP_lm
	.global z80cpu_JP_Z_lm
	.global z80cpu_JP_NZ_lm
	.global z80cpu_JP_C_lm
	.global z80cpu_JP_NC_lm
	.global z80cpu_JP_PE_lm
	.global z80cpu_JP_PO_lm
	.global z80cpu_JP_M_lm
	.global z80cpu_JP_P_lm

	.global z80cpu_JR_e
	.global z80cpu_JR_Z_e
	.global z80cpu_JR_NZ_e
	.global z80cpu_JR_C_e
	.global z80cpu_JR_NC_e

	.global z80cpu_DJNZ_e

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

#macro JP_IrrI $1, $2
	xld.uh %PC, [%CPU+$2]		; %PC = rr
	add    %PC, %MEM		; %PC = mem+rr
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_JP_IHLI:
	JP_IrrI CYCLE_JP_IHLI, HL
z80cpu_JP_IIXI:
	JP_IrrI CYCLE_JP_IIXI, IX
z80cpu_JP_IIYI:
	JP_IrrI CYCLE_JP_IIYI, IY

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

;
; [note]
;	* PCをロードするときに、
;		ld.ub %t0, [%PC]+	; %t0 = m
;		ld.ub %PC, [%PC]+	; %PC = l
;	 としないよう注意してください。
;	 "ld.ub %PC, [%PC]+"は、読み込んだ値を+1してしまいます。
;	 正しくは、
;		ld.ub %t0, [%PC]+	; %t0 = m
;		ld.ub %PC, [%PC]	; %PC = l
;	 です。
;	 ↓Sun Feb 13 03:00:00 JST 2005 Naoyuki Sawa 追記
;	 再度確認したところ、"ld.ub %PC,[%PC]+"は読み込んだ値を+1するのではなく、
;	 もともとの%PCの値+1が結果となるようです。
;	 たとえば、
;		ld.ub %r10,memory
;		ld.ub %r10,[%r10]+
;	 というコードを実行したあとの%r10の値は、memory+1となり、
;	 [memory]から読み込んだメモリの内容は破棄されてしまうようです。
;	 CPUの内部では、次のような処理が行われているものと推測します。
;		tmp = %rs(=%r10)
;		%rd(=%r10) = [tmp]
;		%rs(=%r10) = tmp + 1
;	 同様に、ハーフワードサイズの読み込みを行った場合の%r10の値はmemory+2、
;	 ワードサイズの読み込みを行った場合の%r10の値は%memory+4となりました。
;	 コードや読み込み先データの位置をSRAMおよび高速RAMに配置換えしたり、
;	 24MHzと48MHzモードを確認したところ、すべて以上の結果となりました。
;	 "ld.ub %PC,[%PC]+"の振る舞いを、明示的に使う利点は無いと思います。
;	 オートインクリメントメモリアクセスでは、転送元・転送先に同じレジスタを
;	 ★絶対に★指定しないよう、注意してください。
;
z80cpu_JP_lm:
	ld.ub %t0, [%PC]+		; %t0 = m
	ld.ub %PC, [%PC]		; %PC = l
	xsll  %PC, 8			; %PC = lm
	or    %PC, %t0
	add   %PC, %MEM			; %PC = mem+lm
	ret.d
	sub %CYCLE, CYCLE_JP_lm	; *delay*

;
; [note]
;	* 条件成立/不成立にかかわらず、JP c lmの消費サイクル数はJP lmと同じです。
;	  条件成立時は、JP lmの末尾にてCycleを減らします。
;	  条件不成立時は、JP c lmの末尾にてCycleを減らします。
;
#macro JP_c_lm $1, $2
	xand %r9, %F, $2		; if F($2) then
	xjrne z80cpu_JP_lm		;   JP lm
	xadd %PC, %PC, 2		; else skip lm
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_JP_Z_lm:
	JP_c_lm CYCLE_JP_Z_lm , ZF
z80cpu_JP_C_lm:
	JP_c_lm CYCLE_JP_C_lm , CF
z80cpu_JP_PE_lm:
	JP_c_lm CYCLE_JP_PE_lm, PF
z80cpu_JP_M_lm:
	JP_c_lm CYCLE_JP_M_lm , SF

;
; [note]
;	* 条件成立/不成立にかかわらず、JP c lmの消費サイクル数はJP lmと同じです。
;	  条件成立時は、JP lmの末尾にてCycleを減らします。
;	  条件不成立時は、JP c lmの末尾にてCycleを減らします。
;
#macro JP_Nc_lm $1, $2
	xand %r9, %F, $2		; if !F($2) then
	xjreq z80cpu_JP_lm		;   JP lm
	xadd %PC, %PC, 2		; else skip lm
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_JP_NZ_lm:
	JP_Nc_lm CYCLE_JP_NZ_lm, ZF
z80cpu_JP_NC_lm:
	JP_Nc_lm CYCLE_JP_NC_lm, CF
z80cpu_JP_PO_lm:
	JP_Nc_lm CYCLE_JP_PO_lm, PF
z80cpu_JP_P_lm:
	JP_Nc_lm CYCLE_JP_P_lm , SF

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

z80cpu_JR_e:
	ld.b %t0, [%PC]+		; %t0 = e (signed)
	add  %PC, %t0			; %PC = PC+e
	ret.d
	sub %CYCLE, CYCLE_JR_e		; *delay*

;
; [note]
;	* 条件成立時は、JR c eの消費サイクル数はJR eと同じです。
;	  条件成立時は、JR eの末尾にてCycleを減らします。
;	* 条件不成立時は、JR c eの消費サイクル数はJR eと異なります。
;	  条件不成立時は、JR c eの末尾にてCycleを減らします。
;
#macro JR_c_e $1, $2
	xand %r9, %F, $2		; if F($2) then
	xjrne z80cpu_JR_e		;   JR e
	xadd %PC, %PC, 1		; else skip e
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

;
; [note]
;	* 条件成立時は、JR c eの消費サイクル数はJR eと同じです。
;	  条件成立時は、JR eの末尾にてCycleを減らします。
;	* 条件不成立時は、JR c eの消費サイクル数はJR eと異なります。
;	  条件不成立時は、JR c eの末尾にてCycleを減らします。
;
z80cpu_JR_Z_e:
	JR_c_e CYCLE_JR_Z_e, ZF
z80cpu_JR_C_e:
	JR_c_e CYCLE_JR_C_e, CF

#macro JR_Nc_e $1, $2
	xand %r9, %F, $2		; if !F($2) then
	xjreq z80cpu_JR_e		;   JR e
	xadd %PC, %PC, 1		; else skip e
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_JR_NZ_e:
	JR_Nc_e CYCLE_JR_NZ_e, ZF
z80cpu_JR_NC_e:
	JR_Nc_e CYCLE_JR_NC_e, CF

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

;
; [note]
;	* B-1!=0の場合、追加サイクル数=5で、分岐を行います。
;
z80cpu_DJNZ_e:
	xld.ub %t0, [%CPU+B]		; %t0 = B
	xsub   %t0, %t0, 1		; %t0 = B-1
	xld.b [%CPU+B], %t0		; B   = B-1
	ld.b   %t0, [%PC]+		; %t0 = e (signed)
	jreq 3				; if B-1!=0 then
	add    %PC, %t0			;   %PC   = PC+e    (skip?)
	sub    %CYCLE, 5		;   Cycle = Cycle-5 (skip?)
	ret.d
	sub %CYCLE, CYCLE_DJNZ_e	; *delay*

;****************************************************************************
;	Call and Return Group
;****************************************************************************

	.global z80cpu_CALL_lm
	.global z80cpu_CALL_Z_lm
	.global z80cpu_CALL_NZ_lm
	.global z80cpu_CALL_C_lm
	.global z80cpu_CALL_NC_lm
	.global z80cpu_CALL_PE_lm
	.global z80cpu_CALL_PO_lm
	.global z80cpu_CALL_M_lm
	.global z80cpu_CALL_P_lm

	.global z80cpu_RET
	.global z80cpu_RET_Z
	.global z80cpu_RET_NZ
	.global z80cpu_RET_C
	.global z80cpu_RET_NC
	.global z80cpu_RET_PE
	.global z80cpu_RET_PO
	.global z80cpu_RET_M
	.global z80cpu_RET_P

	.global z80cpu_RETI
	.global z80cpu_RETN

	.global z80cpu_RST_00H
	.global z80cpu_RST_08H
	.global z80cpu_RST_10H
	.global z80cpu_RST_18H
	.global z80cpu_RST_20H
	.global z80cpu_RST_28H
	.global z80cpu_RST_30H
	.global z80cpu_RST_38H

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

z80cpu_CALL_lm:
	ld.w  %a0 , %PC			; %a0 = mem+PC
	ld.ub %t0, [%a0]+		; %t0 = m, %a0 = mem+PC+1
	ld.ub %PC, [%a0]+		; %PC = l, %a0 = mem+PC+2
	xsll  %PC, 8			; %PC = lm
	or    %PC, %t0
	add   %PC, %MEM			; %PC = mem+lm
	xcall.d z80cpu_push		; push  PC+2
	sub   %a0, %MEM			; %a0 = PC+2 *delay*
	ret.d
	sub %CYCLE, CYCLE_CALL_lm	; *delay*

;
; [note]
;	* 条件成立時は、CALL c lmの消費サイクル数はCALL lmと同じです。
;	  条件成立時は、CALL lmの末尾にてCycleを減らします。
;	* 条件不成立時は、CALL c lmの消費サイクル数はCALL lmと異なります。
;	  条件不成立時は、CALL c lmの末尾にてCycleを減らします。
;
#macro CALL_c_lm $1, $2
	xand %r9, %F, $2		; if F($2) then
	xjrne z80cpu_CALL_lm		;   CALL lm
	xadd %PC, %PC, 2		; else skip lm
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_CALL_Z_lm:
	CALL_c_lm CYCLE_CALL_Z_lm , ZF
z80cpu_CALL_C_lm:
	CALL_c_lm CYCLE_CALL_C_lm , CF
z80cpu_CALL_PE_lm:
	CALL_c_lm CYCLE_CALL_PE_lm, PF
z80cpu_CALL_M_lm:
	CALL_c_lm CYCLE_CALL_M_lm , SF

;
; [note]
;	* 条件成立時は、CALL c lmの消費サイクル数はCALL lmと同じです。
;	  条件成立時は、CALL lmの末尾にてCycleを減らします。
;	* 条件不成立時は、CALL c lmの消費サイクル数はCALL lmと異なります。
;	  条件不成立時は、CALL c lmの末尾にてCycleを減らします。
;
#macro CALL_Nc_lm $1, $2
	xand %r9, %F, $2		; if !F($2) then
	xjreq z80cpu_CALL_lm		;   CALL lm
	xadd %PC, %PC, 2		; else skip lm
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_CALL_NZ_lm:
	CALL_Nc_lm CYCLE_CALL_NZ_lm, ZF
z80cpu_CALL_NC_lm:
	CALL_Nc_lm CYCLE_CALL_NC_lm, CF
z80cpu_CALL_PO_lm:
	CALL_Nc_lm CYCLE_CALL_PO_lm, PF
z80cpu_CALL_P_lm:
	CALL_Nc_lm CYCLE_CALL_P_lm , SF

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

z80cpu_RET_cc:
	xsub %CYCLE, %CYCLE, 1		; RET c条件成立時の追加サイクル数=1
z80cpu_RET:
	xcall z80cpu_pop		; %a0 = PC
	add  %a0 , %MEM			; %a0 = mem+PC
	ld.w %PC, %a0			; %PC = mem+PC
	ret.d
	sub %CYCLE, CYCLE_RET		; *delay*

;
; [note]
;	* 条件成立時は、RET cの消費サイクル数はRET+1です。
;	  条件成立時は、RETの先頭および末尾にてCycleを減らします。
;	* 条件不成立時は、RET cの消費サイクル数はRETと異なります。
;	  条件不成立時は、RET cの末尾にてCycleを減らします。
;
#macro RET_c $1, $2
	xand %r9, %F, $2		; if F($2) then
	xjrne z80cpu_RET_cc		;   Cycle = Cycle-1, RET
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_RET_Z:
	RET_c CYCLE_RET_Z , ZF
z80cpu_RET_C:
	RET_c CYCLE_RET_C , CF
z80cpu_RET_PE:
	RET_c CYCLE_RET_PE, PF
z80cpu_RET_M:
	RET_c CYCLE_RET_M , SF

;
; [note]
;	* 条件成立時は、RET cの消費サイクル数はRET+1です。
;	  条件成立時は、RETの先頭および末尾にてCycleを減らします。
;	* 条件不成立時は、RET cの消費サイクル数はRETと異なります。
;	  条件不成立時は、RET cの末尾にてCycleを減らします。
;
#macro RET_Nc $1, $2
	xand %r9, %F, $2		; if !F($2) then
	xjreq z80cpu_RET_cc		;   Cycle = Cycle-1, RET
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_RET_NZ:
	RET_Nc CYCLE_RET_NZ, ZF
z80cpu_RET_NC:
	RET_Nc CYCLE_RET_NC, CF
z80cpu_RET_PO:
	RET_Nc CYCLE_RET_PO, PF
z80cpu_RET_P:
	RET_Nc CYCLE_RET_P , SF

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

z80cpu_RETI:
	xcall z80cpu_pop		; %a0 = PC
	add  %a0, %MEM			; %a0 = mem+PC
	ld.w %PC, %a0			; %PC = mem+PC
	xjp.d z80cpu_CHECK_PENDING	; 保留割り込みの実行を検査します。
	sub %CYCLE, CYCLE_RETI		; *delay*

z80cpu_RETN:
	xcall z80cpu_pop		; %a0 = PC
	add    %a0, %MEM		; %a0 = mem+PC
	ld.w   %PC, %a0			; %PC = mem+PC
	xld.ub %t0, [%CPU+IFF2]		; %t0 = IFF2
	xld.b [%CPU+IFF1], %t0		; IFF1 = %t0
	xjp.d z80cpu_CHECK_PENDING	; 保留割り込みの実行を検査します。
	sub %CYCLE, CYCLE_RETN		; *delay*

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

#macro RST_p $1, $2
	ld.w %a0, %PC			; %a0 = mem+PC
	xcall.d z80cpu_push		; push  PC
	sub  %a0, %MEM			; %a0 = PC *delay*
	xadd %PC, %MEM, $2		; %PC = mem+$2
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_RST_00H:
	RST_p CYCLE_RST_00H, 0x00
z80cpu_RST_08H:
	RST_p CYCLE_RST_08H, 0x08
z80cpu_RST_10H:
	RST_p CYCLE_RST_10H, 0x10
z80cpu_RST_18H:
	RST_p CYCLE_RST_18H, 0x18
z80cpu_RST_20H:
	RST_p CYCLE_RST_20H, 0x20
z80cpu_RST_28H:
	RST_p CYCLE_RST_28H, 0x28
z80cpu_RST_30H:
	RST_p CYCLE_RST_30H, 0x30
z80cpu_RST_38H:
	RST_p CYCLE_RST_38H, 0x38

;****************************************************************************
;	Input and Output Group
;****************************************************************************

	.global z80cpu_IN_A_ICI
	.global z80cpu_IN_B_ICI
	.global z80cpu_IN_C_ICI
	.global z80cpu_IN_D_ICI
	.global z80cpu_IN_E_ICI
	.global z80cpu_IN_H_ICI
	.global z80cpu_IN_L_ICI
	.global z80cpu_IN_A_InI

	.global z80cpu_INI
	.global z80cpu_INIR
	.global z80cpu_IND
	.global z80cpu_INDR

	.global z80cpu_OUT_ICI_A
	.global z80cpu_OUT_ICI_B
	.global z80cpu_OUT_ICI_C
	.global z80cpu_OUT_ICI_D
	.global z80cpu_OUT_ICI_E
	.global z80cpu_OUT_ICI_H
	.global z80cpu_OUT_ICI_L
	.global z80cpu_OUT_InI_A

	.global z80cpu_OUTI
	.global z80cpu_OTIR
	.global z80cpu_OUTD
	.global z80cpu_OTDR

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

z80cpu_IN_A_ICI:
	xcall z80cpu_in
	ld.w %A, %a0			; %A = IN (C)
	ret.d
	sub %CYCLE, CYCLE_IN_A_ICI	; *delay*

#macro IN_r_ICI $1, $2
	xcall z80cpu_in
	xld.b [%CPU+$2], %a0		; r = IN (C)
	ret.d
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_IN_B_ICI:
	IN_r_ICI CYCLE_IN_B_ICI, B
z80cpu_IN_C_ICI:
	IN_r_ICI CYCLE_IN_C_ICI, C
z80cpu_IN_D_ICI:
	IN_r_ICI CYCLE_IN_D_ICI, D
z80cpu_IN_E_ICI:
	IN_r_ICI CYCLE_IN_E_ICI, E
z80cpu_IN_H_ICI:
	IN_r_ICI CYCLE_IN_H_ICI, H
z80cpu_IN_L_ICI:
	IN_r_ICI CYCLE_IN_L_ICI, L

;
;	Condition Bits Affected: None
;
; [note]
;	* "IN A,(C)"とはフラグ変化が異なることに注意してください。
;
z80cpu_IN_A_InI:
	xld.w  %r11, [%CPU+IN]		; %r11 = IN
	ld.ub  %r12, [%PC]+		; %r12 = n|A<<8
	xsll   %A, 8			; (アドレスバスのbit15-8にはAレジスタの値が出力されます)
	call.d %r11			; %r10 = IN (n|A<<8)
	or     %r12, %A			; *delay*
	ld.ub  %A, %r10			; (戻り値のbit31-8をClear。必要です!!)
	xld.w  %CPU, z80cpu		; %r4復元
	xld.w  %MEM, z80mem		; %r5復元
	ret.d
	sub %CYCLE, CYCLE_IN_A_InI	; *delay*

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

;
;	S	is unknown
;	Z	is set if B-1 is 0, reset otherwise
;	H	is unknown
;	P/V	is unknown
;	N	is set
;	C	is not affected
;
; [note]
;	* フラグ変化は"DEC B"に等価です。
;
z80cpu_INI:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	xcall.d z80cpu_in		; %a0 = IN (C)
	add    %s0, %MEM		; %s0 = mem+HL *delay*
	ld.b  [%s0]+, %a0		; [mem+HL] = IN (C), %s0 = mem+HL+1
	sub    %s0, %MEM		; %s0 = HL+1
	xld.h [%CPU+HL], %s0		; HL = HL+1
	;
	xld.ub %a0, [%CPU+B]		; %a0 = B
	xcall z80cpu_dec8		; %a0 = B-1
	xld.b [%CPU+B], %a0		; B = B-1
	ret.d
	sub %CYCLE, CYCLE_INI		; *delay*

;
;	S	is unknown
;	Z	is set
;	H	is unknown
;	P/V	is unknown
;	N	is set
;	C	is not affected
;
; [note]
;	* B-1==0の場合、INIRの消費サイクル数はINIと同じです。
;	  従って、INIRの中でCycleを減らす必要はありません。
;	* B-1!=0の場合、INIRの消費サイクル数はINI+5です。
;	  INIR命令を繰り返すために、自身の2バイト分戻ります。
;
z80cpu_INIR:
	xcall z80cpu_INI		; INI
	xand %r9, %F, ZF
	jrne 3
	sub  %PC, 2			; (skip?)
	sub  %CYCLE, 5			; (skip?)
	ret

;
;	S	is unknown
;	Z	is set if B-1 is 0, reset otherwise
;	H	is unknown
;	P/V	is unknown
;	N	is set
;	C	is not affected
;
; [note]
;	* フラグ変化は"DEC B"に等価です。
;
z80cpu_IND:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	xcall.d z80cpu_in		; %a0 = IN (C)
	add    %s0, %MEM		; %s0 = mem+HL *delay*
	ld.b  [%s0], %a0		; [mem+HL] = IN (C)
	sub    %s0, 1			; %s0 = HL-1
	sub    %s0, %MEM		; %s0 = HL-1
	xld.h [%CPU+HL], %s0		; HL = HL-1
	;
	xld.ub %a0, [%CPU+B]		; %a0 = B
	xcall z80cpu_dec8		; %a0 = B-1
	xld.b [%CPU+B], %a0		; B = B-1
	ret.d
	sub %CYCLE, CYCLE_IND		; *delay*

;
;	S	is unknown
;	Z	is set
;	H	is unknown
;	P/V	is unknown
;	N	is set
;	C	is not affected
;
; [note]
;	* B-1==0の場合、INDRの消費サイクル数はINDと同じです。
;	  従って、INDRの中でCycleを減らす必要はありません。
;	* B-1!=0の場合、INDRの消費サイクル数はIND+5です。
;	  INDR命令を繰り返すために、自身の2バイト分戻ります。
;
z80cpu_INDR:
	xcall z80cpu_IND		; IND
	xand %r9, %F, ZF
	jrne 3
	sub  %PC, 2			; (skip?)
	sub  %CYCLE, 5			; (skip?)
	ret

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

;
;	Condition Bits Affected: None
;
z80cpu_OUT_ICI_A:
	ld.w %a0, %A			; %a0 = A
	xjp.d z80cpu_out
	sub %CYCLE, CYCLE_OUT_ICI_A	; *delay*

;
;	Condition Bits Affected: None
;
#macro OUT_ICI_r $1, $2
	xld.ub %a0, [%CPU+$2]		; %a0 = r
	xjp.d z80cpu_out
	sub %CYCLE, $1			; *delay*
#endm

z80cpu_OUT_ICI_B:
	OUT_ICI_r CYCLE_OUT_ICI_B, B
z80cpu_OUT_ICI_C:
	OUT_ICI_r CYCLE_OUT_ICI_C, C
z80cpu_OUT_ICI_D:
	OUT_ICI_r CYCLE_OUT_ICI_D, D
z80cpu_OUT_ICI_E:
	OUT_ICI_r CYCLE_OUT_ICI_E, E
z80cpu_OUT_ICI_H:
	OUT_ICI_r CYCLE_OUT_ICI_H, H
z80cpu_OUT_ICI_L:
	OUT_ICI_r CYCLE_OUT_ICI_L, L

;
;	Condition Bits Affected: None
;
z80cpu_OUT_InI_A:
	xld.w  %r11, [%CPU+OUT]		; %r11 = OUT
	ld.ub  %r12, [%PC]+		; %r12 = n
	ld.w   %r13, %A			; %r12 = n|A<<8
	xsll   %r13, 8			; (アドレスバスのbit15-8にはAレジスタの値が出力されます)
	or     %r12, %r13
	call.d %r11			; OUT (n|A<<8), A
	ld.w   %r13, %A			; %r13 = A *delay*
	xld.w  %CPU, z80cpu		; %r4復元
	xld.w  %MEM, z80mem		; %r5復元
	ret.d
	sub %CYCLE, CYCLE_OUT_InI_A	; *delay*

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

;
;	S	is unknown
;	Z	is set if B-1 is 0, reset otherwise
;	H	is unknown
;	P/V	is unknown
;	N	is set
;	C	is not affected
;
; [note]
;	* フラグ変化は"DEC B"に等価です。
;
z80cpu_OUTI:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	add    %s0, %MEM		; %s0 = mem+HL
	ld.ub  %a0, [%s0]+		; %a0 = [mem+HL], %s0 = mem+HL+1
	xcall.d z80cpu_out		; OUT (C), [mem+HL]
	sub    %s0, %MEM		; %s0 = HL+1 *delay*
	xld.h [%CPU+HL], %s0		; HL = HL+1
	;
	xld.ub %a0, [%CPU+B]		; %a0 = B
	xcall z80cpu_dec8		; %a0 = B-1
	xld.b [%CPU+B], %a0		; B = B-1
	ret.d
	sub %CYCLE, CYCLE_OUTI		; *delay*

;
;	S	is unknown
;	Z	is set
;	H	is unknown
;	P/V	is unknown
;	N	is set
;	C	is not affected
;
; [note]
;	* B-1==0の場合、OTIRの消費サイクル数はOUTIと同じです。
;	  従って、OTIRの中でCycleを減らす必要はありません。
;	* B-1!=0の場合、OTIRの消費サイクル数はOUTI+5です。
;	  OTIR命令を繰り返すために、自身の2バイト分戻ります。
;
z80cpu_OTIR:
	xcall z80cpu_OUTI		; OUTI
	xand %r9, %F, ZF
	jrne 3
	sub  %PC, 2			; (skip?)
	sub  %CYCLE, 5			; (skip?)
	ret

;
;	S	is unknown
;	Z	is set if B-1 is 0, reset otherwise
;	H	is unknown
;	P/V	is unknown
;	N	is set
;	C	is not affected
;
; [note]
;	* フラグ変化は"DEC B"に等価です。
;
z80cpu_OUTD:
	xld.uh %s0, [%CPU+HL]		; %s0 = HL
	add    %s0, %MEM		; %s0 = mem+HL
	ld.ub  %a0, [%s0]		; %a0 = [mem+HL]
	sub    %s0, 1			; %s0 = mem+HL-1
	xcall.d z80cpu_out		; OUT (C), [mem+HL]
	sub    %s0, %MEM		; %s0 = HL-1 *delay*
	xld.h [%CPU+HL], %s0		; HL = HL-1
	;
	xld.ub %a0, [%CPU+B]		; %a0 = B
	xcall z80cpu_dec8		; %a0 = B-1
	xld.b [%CPU+B], %a0		; B = B-1
	ret.d
	sub %CYCLE, CYCLE_OUTD		; *delay*

;
;	S	is unknown
;	Z	is set
;	H	is unknown
;	P/V	is unknown
;	N	is set
;	C	is not affected
;
; [note]
;	* B-1==0の場合、OTDRの消費サイクル数はOUTDと同じです。
;	  従って、OTDRの中でCycleを減らす必要はありません。
;	* B-1!=0の場合、OTDRの消費サイクル数はOUTD+5です。
;	  OTDR命令を繰り返すために、自身の2バイト分戻ります。
;
z80cpu_OTDR:
	xcall z80cpu_OUTD		; OUTD
	xand %r9, %F, ZF
	jrne 3
	sub  %PC, 2			; (skip?)
	sub  %CYCLE, 5			; (skip?)
	ret

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