misc/fullpatfnc.s- Source code ソースコード - XEiJ - STUDIO KAMADA
misc/fullpatfnc.s

    ;========================================================================================
    ;  fullpatfnc.s
    ;  Copyright (C) 2003-2026 Makoto Kamada
    ;
    ;  This file is part of the XEiJ (X68000 Emulator in Java).
    ;  You can use, modify and redistribute the XEiJ if the conditions are met.
    ;  Read the XEiJ License for more details.
    ;  https://stdkmd.net/xeij/
    ;========================================================================================

    	.include	control2.mac
    	.include	doscall.mac
    	.include	fnc.equ
    	.include	iocscall.mac
    	.include	sprc.equ

    ;インフォメーションテーブル
    information_table:
    	.dc.l	init_routine		;初期化ルーチン
    	.dc.l	run_routine		;RUNルーチン
    	.dc.l	end_routine		;ENDルーチン
    	.dc.l	system_routine		;SYSTEM/EXITルーチン
    	.dc.l	break_routine		;BREAK/CTRL+Cルーチン
    	.dc.l	ctrld_routine		;CTRL+D(外部関数初期化)ルーチン
    	.dcb.l	2,reserved		;予約
    	.dc.l	token_table		;トークンテーブル
    	.dc.l	param_table		;パラメータテーブル
    	.dc.l	func_table		;実行アドレステーブル
    	.dcb.l	5,0			;空き

    ;初期化ルーチン
    init_routine:
    ;RUNルーチン
    run_routine:
    ;ENDルーチン
    end_routine:
    ;SYSTEM/EXITルーチン
    system_routine:
    ;BREAK/CTRL+Cルーチン
    break_routine:
    ;予約
    reserved:
    	rts

    ;CTRL+D(外部関数初期化)ルーチン
    ctrld_routine:
    	IOCS	_SP_OFF
    	rts

    ;トークンテーブル
    token_table:
    	.dc.b	'bg_fill',0
    	.dc.b	'bg_get',0
    	.dc.b	'bg_put',0
    	.dc.b	'bg_scroll',0
    	.dc.b	'bg_set',0
    	.dc.b	'bg_stat',0
    	.dc.b	'sp_clr',0
    	.dc.b	'sp_color',0
    	.dc.b	'sp_def',0
    	.dc.b	'sp_disp',0
    	.dc.b	'sp_init',0
    	.dc.b	'sp_move',0
    	.dc.b	'sp_off',0
    	.dc.b	'sp_on',0
    	.dc.b	'sp_pat',0
    	.dc.b	'sp_set',0
    	.dc.b	'sp_stat',0
    	.dc.b	'sp_wait',0
    	.dc.b	0
    	.even

    ;パラメータテーブル
    param_table:
    	.dc.l	param_bg_fill
    	.dc.l	param_bg_get
    	.dc.l	param_bg_put
    	.dc.l	param_bg_scroll
    	.dc.l	param_bg_set
    	.dc.l	param_bg_stat
    	.dc.l	param_sp_clr
    	.dc.l	param_sp_color
    	.dc.l	param_sp_def
    	.dc.l	param_sp_disp
    	.dc.l	param_sp_init
    	.dc.l	param_sp_move
    	.dc.l	param_sp_off
    	.dc.l	param_sp_on
    	.dc.l	param_sp_pat
    	.dc.l	param_sp_set
    	.dc.l	param_sp_stat
    	.dc.l	param_sp_wait

    ;実行アドレステーブル
    func_table:
    	.dc.l	func_bg_fill
    	.dc.l	func_bg_get
    	.dc.l	func_bg_put
    	.dc.l	func_bg_scroll
    	.dc.l	func_bg_set
    	.dc.l	func_bg_stat
    	.dc.l	func_sp_clr
    	.dc.l	func_sp_color
    	.dc.l	func_sp_def
    	.dc.l	func_sp_disp
    	.dc.l	func_sp_init
    	.dc.l	func_sp_move
    	.dc.l	func_sp_off
    	.dc.l	func_sp_on
    	.dc.l	func_sp_pat
    	.dc.l	func_sp_set
    	.dc.l	func_sp_stat
    	.dc.l	func_sp_wait

    ;----------------------------------------------------------------
    ;int bg_fill(char t,int c)
    ;	バックグラウンドテキストをキャラクタで埋め尽くします。
    ;	t	テキスト番号。0～3
    ;	c	キャラクタ。0～65535
    param_bg_fill:
    	.dc.w	P_CHAR
    	.dc.w	P_INT
    	.dc.w	R_INT
    func_bg_fill:
    	moveq.l	#0,d1
    	move.b	P1_CHAR(sp),d1		;d1=テキスト番号。0～3
    	goto	<cmp.b #3,d1>,hi,text_number_error
    	move.l	P2_INT(sp),d2		;d2=キャラクタ。0～65535
    	goto	<cmp.l #65535,d2>,hi,character_error
    	IOCS	_BGTEXTCL
    	goto	<tst.l d0>,mi,screen_mode_error
    	goto	return_zero

    ;----------------------------------------------------------------
    ;int bg_get(char t,char x,char y)
    ;	バックグラウンドテキストからキャラクタを読み出します。
    ;	t	テキスト番号。0～3
    ;	x	X座標。0～63
    ;	y	Y座標。0～63
    ;	戻り値	キャラクタ。0～65535
    param_bg_get:
    	.dc.w	P_CHAR
    	.dc.w	P_CHAR
    	.dc.w	P_CHAR
    	.dc.w	R_INT
    func_bg_get:
    	moveq.l	#0,d1
    	move.b	P1_CHAR(sp),d1		;d1=テキスト番号。0～3
    	goto	<cmp.b #3,d1>,hi,text_number_error
    	moveq.l	#0,d2
    	move.b	P2_CHAR(sp),d2		;d2=X座標。0～63
    	goto	<cmp.b #63,d2>,hi,x_error_64
    	moveq.l	#0,d3
    	move.b	P3_CHAR(sp),d3		;d3=Y座標。0～63
    	goto	<cmp.b #63,d3>,hi,y_error_64
    	IOCS	_BGTEXTGT
    	goto	<tst.l d0>,mi,screen_mode_error
    	goto	return_d0

    ;----------------------------------------------------------------
    ;int bg_put(char t,char x,char y,int c)
    ;	バックグラウンドテキストにキャラクタを書き込みます。
    ;	t	テキスト番号。0～3
    ;	x	X座標。0～63
    ;	y	Y座標。0～63
    ;	c	キャラクタ。0～65535
    param_bg_put:
    	.dc.w	P_CHAR
    	.dc.w	P_CHAR
    	.dc.w	P_CHAR
    	.dc.w	P_INT
    	.dc.w	R_INT
    func_bg_put:
    	moveq.l	#0,d1
    	move.b	P1_CHAR(sp),d1		;d1=テキスト番号。0～3
    	goto	<cmp.b #3,d1>,hi,text_number_error
    	moveq.l	#0,d2
    	move.b	P2_CHAR(sp),d2		;d2=X座標。0～63
    	goto	<cmp.b #63,d2>,hi,x_error_64
    	moveq.l	#0,d3
    	move.b	P3_CHAR(sp),d3		;d3=Y座標。0～63
    	goto	<cmp.b #63,d3>,hi,y_error_64
    	move.l	P4_INT(sp),d4		;d4=キャラクタ。0～65535
    	goto	<cmp.l #65535,d4>,hi,character_error
    	IOCS	_BGTEXTST
    	goto	<tst.l d0>,mi,screen_mode_error
    	goto	return_zero

    ;----------------------------------------------------------------
    ;int bg_scroll(char b,[int x],[int y],[char v])
    ;	バックグラウンドスクロールレジスタを設定します。
    ;	b	バックグラウンド番号。0～1
    ;	x	X座標。0～1023。省略すると変更しない
    ;	y	Y座標。0～1023。省略すると変更しない
    ;	v	VDISPの立ち下がり。0=待つ,1=待たない。省略すると1
    param_bg_scroll:
    	.dc.w	P_CHAR
    	.dc.w	P_OPT|P_INT
    	.dc.w	P_OPT|P_INT
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	R_INT
    func_bg_scroll:
    	moveq.l	#0,d1
    	move.b	P1_CHAR(sp),d1		;d1=バックグラウンド番号。0～1
    	goto	<cmp.b #1,d1>,hi,background_number_error
    	lea.l	SPRC_RESOLUTION,a1
    	IOCS	_B_WPEEK
    	and.w	#3,d0
    	if	eq			;256x256
    		moveq.l	#-1,d2			;省略すると変更しない
    		if	<tst.w P2_TYPE(sp)>,pl
    			move.l	P2_INT(sp),d2		;d2=X座標。0～1023
    			goto	<cmp.l #511,d2>,hi,x_error_512
    		endif
    		moveq.l	#-1,d3			;省略すると変更しない
    		if	<tst.w P3_TYPE(sp)>,pl
    			move.l	P3_INT(sp),d3		;d3=Y座標。0～1023
    			goto	<cmp.l #511,d3>,hi,y_error_512
    		endif
    	else				;512x512
    		moveq.l	#-1,d2			;省略すると変更しない
    		if	<tst.w P2_TYPE(sp)>,pl
    			move.l	P2_INT(sp),d2		;d2=X座標。0～1023
    			goto	<cmp.l #1023,d2>,hi,x_error_1024
    		endif
    		moveq.l	#-1,d3			;省略すると変更しない
    		if	<tst.w P3_TYPE(sp)>,pl
    			move.l	P3_INT(sp),d3		;d3=Y座標。0～1023
    			goto	<cmp.l #1023,d3>,hi,y_error_1024
    		endif
    	endif
    	moveq.l	#1,d4			;省略すると1
    	if	<tst.w P4_TYPE(sp)>,pl
    		move.b	P4_CHAR(sp),d4		;d4=VDISPの立ち下がり。0=待つ,1=待たない
    		goto	<cmp.b #1,d4>,hi,vdisp_error
    	endif
    	ror.l	#1,d4
    	or.l	d4,d1
    	IOCS	_BGSCRLST
    	goto	<tst.l d0>,mi,screen_mode_error
    	goto	return_zero

    ;----------------------------------------------------------------
    ;int bg_set(char b[,char t,char d])
    ;	バックグラウンド制御レジスタを設定します。
    ;	b	バックグラウンド番号。0～1
    ;	t	テキスト番号。0～3。省略すると変更しない
    ;	d	表示の有無。0～1。省略すると変更しない
    param_bg_set:
    	.dc.w	P_CHAR
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	R_INT
    func_bg_set:
    	moveq.l	#0,d1
    	move.b	P1_CHAR(sp),d1		;d1=バックグラウンド番号。0～1
    	goto	<cmp.b #1,d1>,hi,background_number_error
    	moveq.l	#-1,d2			;省略すると変更しない
    	if	<tst.w P2_TYPE(sp)>,pl
    		moveq.l	#0,d2
    		move.b	P2_CHAR(sp),d2		;d2=テキスト番号。0～3
    		goto	<cmp.b #3,d2>,hi,text_number_error
    	endif
    	moveq.l	#-1,d3			;省略すると変更しない
    	if	<tst.w P3_TYPE(sp)>,pl
    		moveq.l	#0,d3
    		move.b	P3_CHAR(sp),d3		;d3=表示の有無。0～1
    		goto	<cmp.b #1,d3>,hi,display_error
    	endif
      .if 1
    	ifand	<tst.b d1>,ne,<tst.l d3>,gt	;バックグラウンド1を表示
    		lea.l	SPRC_RESOLUTION,a1
    		IOCS	_B_WPEEK
    		and.w	#3,d0
    		goto	ne,background_1_error
    	endif
      .endif
    	IOCS	_BGCTRLST
    	goto	<tst.l d0>,mi,screen_mode_error
    	goto	return_zero

    ;----------------------------------------------------------------
    ;int bg_stat(char b,char m)
    ;	バックグラウンドスクロールレジスタまたはバックグラウンド制御レジスタを取得します。
    ;	b	バックグラウンド番号。0～1
    ;	m	モード。0～3
    ;		0	X座標。0～1023
    ;		1	Y座標。0～1023
    ;		2	テキスト番号。0～3
    ;		3	表示の有無。0～1
    ;	戻り値	取得した値
    param_bg_stat:
    	.dc.w	P_CHAR
    	.dc.w	P_CHAR
    	.dc.w	R_INT
    func_bg_stat:
    	moveq.l	#0,d1
    	move.b	P1_CHAR(sp),d1		;d1=バックグラウンド番号。0～1
    	goto	<cmp.b #1,d1>,hi,background_number_error
    	move.b	P2_CHAR(sp),d0		;d0=モード。0～3
    	if	eq			;0 X座標。0～1023
    		IOCS	_BGSCRLGT
    		goto	<tst.l d0>,mi,screen_mode_error
    		move.l	d2,d0
    		goto	return_d0
    	endif
    	subq.b	#2,d0
    	if	lo			;1 Y座標。0～1023
    		IOCS	_BGSCRLGT
    		goto	<tst.l d0>,mi,screen_mode_error
    		move.l	d3,d0
    		goto	return_d0
    	endif
    	if	eq			;2 テキスト番号。0～3
    		IOCS	_BGCTRLGT
    		goto	<tst.l d0>,mi,screen_mode_error
    		lsr.l	#1,d0
    		goto	return_d0
    	endif
    	subq.b	#2,d0
    	if	lo			;3 表示の有無。0～1
    		IOCS	_BGCTRLGT
    		goto	<tst.l d0>,mi,screen_mode_error
    		moveq.l	#1,d1
    		and.l	d1,d0
    		goto	return_d0
    	endif
    	goto	mode_error_4

    ;----------------------------------------------------------------
    ;int sp_clr([int p1],[int p2])
    ;	パターンをゼロクリアします。
    ;	p1	開始パターン番号。0～511。省略すると0から
    ;	p2	終了パターン番号。0～511。省略するとp1のみ、両方省略すると511まで
    param_sp_clr:
    	.dc.w	P_OPT|P_INT
    	.dc.w	P_OPT|P_INT
    	.dc.w	R_INT
    func_sp_clr:
    	moveq.l	#-1,d2
    	if	<tst.w P1_TYPE(sp)>,pl
    		move.l	P1_INT(sp),d2		;d2=開始パターン番号。0～511
    		goto	<cmp.l #511,d2>,hi,pattern_number_error
    	endif
    	moveq.l	#-1,d3
    	if	<tst.w P2_TYPE(sp)>,pl
    		move.l	P2_INT(sp),d3		;d3=終了パターン番号。0～511
    		goto	<cmp.l #511,d3>,hi,pattern_number_error
    	endif
    	if	<tst.l d2>,mi		;開始パターン番号を省略すると
    		moveq.l	#0,d2			;0から
    		if	<tst.l d3>,mi		;両方省略すると
    			move.l	#511,d3			;511まで
    		endif
    	elif	<tst.l d3>,mi		;終了パターン番号を省略すると
    		move.l	d2,d3			;開始パターン番号のみ
    	endif
    	if	<cmp.l d3,d2>,hi	;終了パターン番号<開始パターン番号のときは
    		exg.l	d2,d3			;入れ替える
    	endif
    	move.l	d2,d1
    	sub.w	d2,d3
    	for	d3
    		IOCS	_SP_CGCLR
    		goto	<tst.l d0>,mi,screen_mode_error
    		addq.w	#1,d1
    	next
    	goto	return_zero

    ;----------------------------------------------------------------
    ;int sp_color(char p,[int c],[char b],[char v])
    ;	スプライトパレットを設定または取得します。
    ;	p	パレットコード。0～15
    ;	c	カラーコード。0～65535。省略すると取得のみ
    ;	b	パレットブロック。1～15。省略すると1
    ;	v	VDISPの立ち下がり。0=待つ,1=待たない。省略すると1
    ;	戻り値	設定前のカラーコード
    param_sp_color:
    	.dc.w	P_CHAR
    	.dc.w	P_OPT|P_INT
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	R_INT
    func_sp_color:
    	moveq.l	#0,d1
    	move.b	P1_CHAR(sp),d1		;d1=パレットコード。0～15
    	goto	<cmp.b #15,d1>,hi,palet_code_error
    	moveq.l	#-1,d3			;省略すると取得のみ
    	if	<tst.w P2_TYPE(sp)>,pl
    		move.l	P2_INT(sp),d3		;d3=カラーコード。0～65535
    		goto	<cmp.l #65535,d3>,hi,color_code_error
    	endif
    	moveq.l	#1,d2			;省略すると1
    	if	<tst.w P3_TYPE(sp)>,pl
    		moveq.l	#0,d2
    		move.b	P3_CHAR(sp),d2		;d2=パレットブロック。1～15
    		gotoor	<>,eq,<cmp.b #15,d2>,hi,palet_block_error
    	endif
    	moveq.l	#1,d4			;省略すると1
    	if	<tst.w P4_TYPE(sp)>,pl
    	;	moveq.l	#0,d4
    		move.b	P4_CHAR(sp),d4		;d4=VDISPの立ち下がり。0=待つ,1=待たない
    		goto	<cmp.b #1,d4>,hi,vdisp_error
    	endif
    	ror.l	#1,d4
    	or.l	d4,d1
    	IOCS	_SPALET
    	goto	return_d0

    ;----------------------------------------------------------------
    ;int sp_def(int p,char/int(a),[char s],[int o])
    ;	パターンを設定します。
    ;	p	パターン番号。0～511
    ;	a	データの配列
    ;	s	サイズ。0=8x8,1=16x16。省略すると1
    ;	o	オフセット。省略すると0
    param_sp_def:
    	.dc.w	P_INT
    	.dc.w	P_DIM1|P_PTR|P_CHAR|P_INT
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	P_OPT|P_INT
    	.dc.w	R_INT
    func_sp_def:
    	move.l	P1_INT(sp),d1		;d1=パターン番号。0～511
    	goto	<cmp.l #511,d1>,hi,pattern_number_error
    	movea.l	P2_INT(sp),a2		;a2=データの配列
    	moveq.l	#1,d2			;省略すると1
    	if	<tst.w P3_TYPE(sp)>,pl
    	;	moveq.l	#0,d2
    		move.b	P3_CHAR(sp),d2		;d2=サイズ。0=8x8,1=16x16
    		goto	<cmp.b #1,d2>,hi,pattern_size_error
    	endif
    	moveq.l	#0,d3			;省略すると0
    	if	<tst.w P4_TYPE(sp)>,pl
    		move.l	P4_INT(sp),d3		;d3=オフセット
    		goto	<cmp.l #65535,d3>,hi,offset_error
    	endif
    	lea.l	D1_DATA(a2),a0		;a0=データの先頭
    	moveq.l	#0,d0
    	move.w	D1_IMAX(a2),d0		;d0=配列の最大要素番号
    	if	<tst.b d2>,eq		;8x8
    		if	<cmpi.w #1,D1_UNIT(a2)>,eq	;char()
    			moveq.l	#8*8-1,d4
    			add.l	d3,d4			;d4=参照する最大要素番号
    			goto	<cmp.l d0,d4>,hi,array_size_error
    			lea.l	-32(sp),sp
    			adda.l	d3,a0			;配列の開始位置
    			movea.l	sp,a1			;バッファの開始位置
    			moveq.l	#4*8-1,d3
    			for	d3
    				move.w	(a0)+,d0		;.H.L
    				lsl.b	#4,d0			;.HL_
    				lsr.w	#4,d0			;_.HL
    				move.b	d0,(a1)+		;HL
    			next
    			movea.l	sp,a1
    			IOCS	_SP_DEFCG
    			lea.l	32(sp),sp
    		else				;int()
    			move.l	d3,d4
    			addq.l	#8-1,d4			;d4=参照する最大要素番号
    			goto	<cmp.l d0,d4>,hi,array_size_error
    			lsl.l	#2,d3
    			lea.l	(a0,d3.l),a1		;配列の開始位置
    			IOCS	_SP_DEFCG
    		endif
    	else				;16x16
    		if	<cmpi.w #1,D1_UNIT(a2)>,eq	;char()
    			move.l	d3,d4
    			add.l	#16*16-1,d4		;d4=参照する最大要素番号
    			goto	<cmp.l d0,d4>,hi,array_size_error
    			lea.l	-128(sp),sp
    			lsl.l	#2,d3
    			adda.l	d3,a0			;配列の開始位置
    			movea.l	sp,a1			;バッファの開始位置
    			moveq.l	#16-1,d3
    			for	d3
    				moveq.l	#4-1,d4
    				for	d4
    					move.w	(a0)+,d0		;.H.L
    					lsl.b	#4,d0			;.HL_
    					lsr.w	#4,d0			;_.HL
    					move.b	d0,(a1)+		;HL
    					move.w	8-2(a0),d0		;.H.L
    					lsl.b	#4,d0			;.HL_
    					lsr.w	#4,d0			;_.HL
    					move.b	d0,64-1(a1)		;HL
    				next
    				addq.l	#8,a0
    			next
    			movea.l	sp,a1
    			IOCS	_SP_DEFCG
    			lea.l	128(sp),sp
    		else				;int()
    			moveq.l	#32-1,d4
    			add.l	d3,d4			;d4=参照する最大要素番号
    			goto	<cmp.l d0,d4>,hi,array_size_error
    			lsl.l	#2,d3
    			lea.l	(a0,d3.l),a1		;配列の開始位置
    			IOCS	_SP_DEFCG
    		endif
    	endif
    	goto	<tst.l d0>,mi,screen_mode_error
    	goto	return_zero

    ;----------------------------------------------------------------
    ;int sp_disp(char m)
    ;	スプライト画面を表示するか選択します。
    ;	m	モード。0～1
    ;		0	表示しない
    ;		1	表示する
    param_sp_disp:
    	.dc.w	P_CHAR
    	.dc.w	R_INT
    func_sp_disp:
    	move.b	P1_CHAR(sp),d0		;d0=モード。0～1
    	if	eq			;0 表示しない
    		IOCS	_SP_OFF
    		goto	return_zero
    	endif
    	subq.b	#2,d0
    	if	lo			;1 表示する
    		IOCS	_SP_ON
    		goto	<tst.l d0>,mi,screen_mode_error
    		goto	return_zero
    	endif
    	goto	mode_error_2

    ;----------------------------------------------------------------
    ;int sp_init()
    ;	スプライト・バックグラウンドを初期化します。
    param_sp_init:
    	.dc.w	R_INT
    func_sp_init:
      .if 1
    	lea.l	4*($100+_SP_INIT).w,a1
    	IOCS	_B_LPEEK
    	movea.l	d0,a1
    	subq.l	#8,a1
    	IOCS	_B_LPEEK
    	goto	<cmpi.l #'FLPT',d0>,ne,fullpat_error
      .endif
    	IOCS	_SP_INIT
    	goto	<tst.l d0>,mi,screen_mode_error
    	goto	return_zero

    ;----------------------------------------------------------------
    ;int sp_move(char s,[int x],[int y],[int p])
    ;	スプライトスクロールレジスタを設定します。
    ;	s	スプライト番号。0～127
    ;	x	X座標。-16～1007。省略すると変更しない
    ;	y	Y座標。-16～1007。省略すると変更しない
    ;	p	パターン番号。0～511。省略すると変更しない
    param_sp_move:
    	.dc.w	P_CHAR
    	.dc.w	P_OPT|P_INT
    	.dc.w	P_OPT|P_INT
    	.dc.w	P_OPT|P_INT
    	.dc.w	R_INT
    func_sp_move:
    	moveq.l	#0,d1
    	move.b	P1_CHAR(sp),d1		;d1=スプライト番号。0～127
    	goto	<tst.b d1>,mi,sprite_number_error
    	moveq.l	#-1,d2			;省略すると変更しない
    	if	<tst.w P2_TYPE(sp)>,pl
    		moveq.l	#16,d2
    		add.l	P2_INT(sp),d2		;d2=X座標。-16～1007
    		goto	<cmp.l #1023,d2>,hi,x_error_1008
    	endif
    	moveq.l	#-1,d3			;省略すると変更しない
    	if	<tst.w P3_TYPE(sp)>,pl
    		moveq.l	#16,d3
    		add.l	P3_INT(sp),d3		;d3=Y座標。-16～1007
    		goto	<cmp.l #1023,d3>,hi,y_error_1008
    	endif
    	moveq.l	#-1,d4			;省略すると変更しない
    	moveq.l	#-1,d5
    	if	<tst.w P4_TYPE(sp)>,pl
    		move.l	P4_INT(sp),d4		;d4=パターン番号。0～511
    		goto	<cmp.l #511,d4>,hi,pattern_number_error
    		moveq.l	#3,d5			;d5=プライオリティは3
    		bset.l	#8,d4			;パレットブロックは1、反転なし
    		if	ne
    			addq.b	#4,d5			;キャラクタbit8→プライオリティbit2
    		endif
    	endif
    	bset.l	#31,d1			;VDISPの立ち下がりを待たない
    	IOCS	_SP_REGST
    	goto	<tst.l d0>,mi,screen_mode_error
    	goto	return_zero

    ;----------------------------------------------------------------
    ;int sp_off([char s1],[char s2])
    ;	スプライトを表示しません。
    ;	s1	開始スプライト番号。0～127。省略すると0から
    ;	s2	終了スプライト番号。0～127。省略するとs1のみ、両方省略すると127まで
    param_sp_off:
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	R_INT
    func_sp_off:
    	moveq.l	#-1,d6
    	if	<tst.w P1_TYPE(sp)>,pl
    		moveq.l	#0,d6
    		move.b	P1_CHAR(sp),d6		;d6=開始スプライト番号。0～127
    		goto	<tst.b d6>,mi,sprite_number_error
    	endif
    	moveq.l	#-1,d7
    	if	<tst.w P2_TYPE(sp)>,pl
    		moveq.l	#0,d7
    		move.b	P2_CHAR(sp),d7		;d7=終了スプライト番号。0～127
    		goto	<tst.b d7>,mi,sprite_number_error
    	endif
    	if	<tst.l d6>,mi		;開始スプライト番号を省略すると
    		moveq.l	#0,d6			;0から
    		if	<tst.l d7>,mi		;両方省略すると
    			moveq.l	#127,d7			;127まで
    		endif
    	elif	<tst.l d7>,mi		;終了スプライト番号を省略すると
    		move.l	d6,d7			;開始スプライト番号のみ
    	endif
    	if	<cmp.l d7,d6>,hi	;終了スプライト番号<開始スプライト番号のときは
    		exg.l	d6,d7			;入れ替える
    	endif
    	move.l	d6,d1
    	bset.l	#31,d1			;VDISPの立ち下がりを待たない
    	sub.w	d6,d7
    	for	d7
    		IOCS	_SP_REGGT
    		goto	<tst.l d0>,mi,screen_mode_error
    		and.b	#.notb.3,d5		;優先順位を0にする
    		IOCS	_SP_REGST
    		addq.w	#1,d1
    	next
    	goto	return_zero

    ;----------------------------------------------------------------
    ;int sp_on([char s1],[char s2])
    ;	スプライトを表示します。
    ;	s1	開始スプライト番号。0～127。省略すると0から
    ;	s2	終了スプライト番号。0～127。省略するとs1のみ、両方省略すると127まで
    param_sp_on:
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	R_INT
    func_sp_on:
    	moveq.l	#-1,d6
    	if	<tst.w P1_TYPE(sp)>,pl
    		moveq.l	#0,d6
    		move.b	P1_CHAR(sp),d6		;d6=開始スプライト番号。0～127
    		goto	<tst.b d6>,mi,sprite_number_error
    	endif
    	moveq.l	#-1,d7
    	if	<tst.w P2_TYPE(sp)>,pl
    		moveq.l	#0,d7
    		move.b	P2_CHAR(sp),d7		;d7=終了スプライト番号。0～127
    		goto	<tst.b d7>,mi,sprite_number_error
    	endif
    	if	<tst.l d6>,mi		;開始スプライト番号を省略すると
    		moveq.l	#0,d6			;0から
    		if	<tst.l d7>,mi		;両方省略すると
    			moveq.l	#127,d7			;127まで
    		endif
    	elif	<tst.l d7>,mi		;終了スプライト番号を省略すると
    		move.l	d6,d7			;開始スプライト番号のみ
    	endif
    	if	<cmp.l d7,d6>,hi	;終了スプライト番号<開始スプライト番号のときは
    		exg.l	d6,d7			;入れ替える
    	endif
    	move.l	d6,d1
    	bset.l	#31,d1			;VDISPの立ち下がりを待たない
    	sub.w	d6,d7
    	for	d7
    		IOCS	_SP_REGGT
    		goto	<tst.l d0>,mi,screen_mode_error
    		or.b	#3,d5			;優先順位を3にする
    		IOCS	_SP_REGST
    		addq.w	#1,d1
    	next
    	goto	return_zero

    ;----------------------------------------------------------------
    ;int sp_pat(int p,char/int(a),[char s],[int o])
    ;	パターンを取得します。
    ;	p	パターン番号。0～511
    ;	a	データの配列
    ;	s	サイズ。0=8x8,1=16x16。省略すると1
    ;	o	オフセット。省略すると0
    param_sp_pat:
    	.dc.w	P_INT
    	.dc.w	P_DIM1|P_PTR|P_CHAR|P_INT
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	P_OPT|P_INT
    	.dc.w	R_INT
    func_sp_pat:
    	move.l	P1_INT(sp),d1		;d1=パターン番号。0～511
    	goto	<cmp.l #511,d1>,hi,pattern_number_error
    	movea.l	P2_INT(sp),a2		;a2=データの配列
    	moveq.l	#1,d2			;省略すると1
    	if	<tst.w P3_TYPE(sp)>,pl
    	;	moveq.l	#0,d2
    		move.b	P3_CHAR(sp),d2		;d2=サイズ。0=8x8,1=16x16
    		goto	<cmp.b #1,d2>,hi,pattern_size_error
    	endif
    	moveq.l	#0,d3			;省略すると0
    	if	<tst.w P4_TYPE(sp)>,pl
    		move.l	P4_INT(sp),d3		;d3=オフセット
    		goto	<cmp.l #65535,d3>,hi,offset_error
    	endif
    	lea.l	D1_DATA(a2),a0		;a0=データの先頭
    	moveq.l	#0,d0
    	move.w	D1_IMAX(a2),d0		;d0=配列の最大要素番号
    	if	<tst.b d2>,eq		;8x8
    		if	<cmpi.w #1,D1_UNIT(a2)>,eq	;char()
    			moveq.l	#8*8-1,d4
    			add.l	d3,d4			;d4=参照する最大要素番号
    			goto	<cmp.l d0,d4>,hi,array_size_error
    			lea.l	-32(sp),sp
    			movea.l	sp,a1
    			IOCS	_SP_GTPCG
    			adda.l	d3,a0			;配列の開始位置
    			movea.l	sp,a1			;バッファの開始位置
    			moveq.l	#4*8-1,d3
    			for	d3
    				clr.w	d0			;____
    				move.b	(a1)+,d0		;__HL
    				lsl.w	#4,d0			;_HL_
    				lsr.b	#4,d0			;_H_L
    				move.w	d0,(a0)+		;_H_L
    			next
    			lea.l	32(sp),sp
    		else				;int()
    			move.l	d3,d4
    			addq.l	#8-1,d4			;d4=参照する最大要素番号
    			goto	<cmp.l d0,d4>,hi,array_size_error
    			lsl.l	#2,d3
    			lea.l	(a0,d3.l),a1		;配列の開始位置
    			IOCS	_SP_GTPCG
    		endif
    	else				;16x16
    		if	<cmpi.w #1,D1_UNIT(a2)>,eq	;char()
    			move.l	d3,d4
    			add.l	#16*16-1,d4		;d4=参照する最大要素番号
    			goto	<cmp.l d0,d4>,hi,array_size_error
    			lea.l	-128(sp),sp
    			movea.l	sp,a1
    			IOCS	_SP_GTPCG
    			lsl.l	#2,d3
    			adda.l	d3,a0			;配列の開始位置
    			movea.l	sp,a1			;バッファの開始位置
    			moveq.l	#16-1,d3
    			for	d3
    				moveq.l	#4-1,d4
    				for	d4
    					clr.w	d0			;____
    					move.b	(a1)+,d0		;__HL
    					lsl.w	#4,d0			;_HL_
    					lsr.b	#4,d0			;_H_L
    					move.w	d0,(a0)+		;_H_L
    					clr.w	d0			;____
    					move.b	64-1(a1),d0		;__HL
    					lsl.w	#4,d0			;_HL_
    					lsr.b	#4,d0			;_H_L
    					move.w	d0,8-2(a0)		;_H_L
    				next
    				addq.l	#8,a0
    			next
    			lea.l	128(sp),sp
    		else				;int()
    			moveq.l	#32-1,d4
    			add.l	d3,d4			;d4=参照する最大要素番号
    			goto	<cmp.l d0,d4>,hi,array_size_error
    			lsl.l	#2,d3
    			lea.l	(a0,d3.l),a1		;配列の開始位置
    			IOCS	_SP_GTPCG
    		endif
    	endif
    	goto	<tst.l d0>,mi,screen_mode_error
    	goto	return_zero

    ;----------------------------------------------------------------
    ;int sp_set(char s,[int x],[int y],[int c],[char p],[char v])
    ;	スプライトスクロールレジスタを設定します。
    ;	s	スプライト番号。0～127
    ;	x	X座標。-16～1007。省略すると変更しない
    ;	y	Y座標。-16～1007。省略すると変更しない
    ;	c	キャラクタ。0～65535。省略すると変更しない
    ;	p	プライオリティ。0～7。省略すると変更しない
    ;	v	VDISPの立ち下がり。0=待つ,1=待たない。省略すると1
    param_sp_set:
    	.dc.w	P_CHAR
    	.dc.w	P_OPT|P_INT
    	.dc.w	P_OPT|P_INT
    	.dc.w	P_OPT|P_INT
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	R_INT
    func_sp_set:
    	moveq.l	#0,d1
    	move.b	P1_CHAR(sp),d1		;d1=スプライト番号。0～127
    	goto	<tst.b d1>,mi,sprite_number_error
    	moveq.l	#-1,d2			;省略すると変更しない
    	if	<tst.w P2_TYPE(sp)>,pl
    		move.l	P2_INT(sp),d2		;d2=X座標。0～1023
    		goto	<cmp.l #1023,d2>,hi,x_error_1024
    	endif
    	moveq.l	#-1,d3			;省略すると変更しない
    	if	<tst.w P3_TYPE(sp)>,pl
    		move.l	P3_INT(sp),d3		;d3=Y座標。0～1023
    		goto	<cmp.l #1023,d3>,hi,y_error_1024
    	endif
    	moveq.l	#-1,d4			;省略すると変更しない
    	if	<tst.w P4_TYPE(sp)>,pl
    		move.l	P4_INT(sp),d4		;d4=キャラクタ。0～65535
    		goto	<cmp.l #65535,d4>,hi,character_error
    	endif
    	moveq.l	#-1,d5			;省略すると変更しない
    	if	<tst.w P5_TYPE(sp)>,pl
    		moveq.l	#0,d5
    		move.b	P5_CHAR(sp),d5		;d5=プライオリティ。0～7
    		goto	<cmp.b #7,d5>,hi,priority_error
    	endif
    	moveq.l	#1,d6			;省略すると1
    	if	<tst.w P6_TYPE(sp)>,pl
    	;	moveq.l	#0,d6
    		move.b	P6_CHAR(sp),d6		;d6=VDISPの立ち下がり。0=待つ,1=待たない
    		goto	<cmp.b #1,d6>,hi,vdisp_error
    	endif
    	ror.l	#1,d6
    	or.l	d6,d1
    	IOCS	_SP_REGST
    	goto	<tst.l d0>,mi,screen_mode_error
    	goto	return_zero

    ;----------------------------------------------------------------
    ;int sp_stat(char s,char m)
    ;	スプライトスクロールレジスタを取得します。
    ;	s	スプライト番号。0～127
    ;	m	モード。0～3
    ;		0	X座標。0～1023
    ;		1	Y座標。0～1023
    ;		2	キャラクタ。0～65535
    ;		3	プライオリティ。0～7
    ;	戻り値	取得した値
    param_sp_stat:
    	.dc.w	P_CHAR
    	.dc.w	P_CHAR
    	.dc.w	R_INT
    func_sp_stat:
    	moveq.l	#0,d1
    	move.b	P1_CHAR(sp),d1		;d1=スプライト番号。0～127
    	goto	<tst.b d1>,mi,sprite_number_error
    	IOCS	_SP_REGGT
    	goto	<tst.l d0>,mi,screen_mode_error
    	move.b	P2_CHAR(sp),d0		;d0=モード。0～3
    	if	eq			;0 X座標。0～1023
    		move.l	d2,d0
    		goto	return_d0
    	endif
    	subq.b	#2,d0
    	if	lo			;1 Y座標。0～1023
    		move.l	d3,d0
    		goto	return_d0
    	endif
    	if	eq			;2 キャラクタ。0～65535
    		move.l	d4,d0
    		goto	return_d0
    	endif
    	subq.b	#2,d0
    	if	lo			;3 プライオリティ。0～7
    		move.l	d5,d0
    		goto	return_d0
    	endif
    	goto	mode_error_4

    ;----------------------------------------------------------------
    ;int sp_wait([char n])
    ;	VDISPの立ち下がりを待ちます。
    ;	n	回数。省略すると1
    param_sp_wait:
    	.dc.w	P_OPT|P_CHAR
    	.dc.w	R_INT
    func_sp_wait:
    	moveq.l	#1,d4			;省略すると1
    	if	<tst.w P1_TYPE(sp)>,pl
    		move.b	P1_CHAR(sp),d4		;d4=回数
    	endif
    	forcontinue	d4
    		moveq.l	#0,d1
    		moveq.l	#-1,d2
    		moveq.l	#-1,d3
    		IOCS	_BGSCRLST
    		goto	<tst.l d0>,mi,screen_mode_error
    	next
    	goto	return_zero

    ;----------------------------------------------------------------
    ;戻り値0で正常終了
    return_zero:
    	moveq.l	#0,d0
    ;正常終了
    ;<d0.l:戻り値
    return_d0:
    	lea.l	return_value(pc),a0	;戻り値。voidのときは不要
    	move.l	d0,R1_INT(a0)		;戻り値
    	moveq.l	#0,d0			;終了コードは0。エラーメッセージは不要
    	rts

    ;----------------------------------------------------------------
    ;エラー終了
    ;<d0.l:エラーコード。0以外。負はDOSコールエラー
    ;<a1.l:エラーメッセージ。DOSコールエラーのときは不要
    ;	5はCTRL+E 現在のカーソル以降1行を消す
    error_exit:
    	lea.l	return_value(pc),a0	;戻り値。voidのときは不要
    	move.l	d0,R1_INT(a0)		;error offのときの戻り値。エラーコード
    	rts

    array_size_error:
    	moveq.l	#1,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'配列のサイズが範囲外です',5,0
    	.even

    background_1_error:
    	moveq.l	#2,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'現在の画面モードではバックグラウンド1を表示できません',5,0
    	.even

    background_number_error:
    	moveq.l	#3,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'バックグラウンド番号が0～1の範囲外です',5,0
    	.even

    character_error:
    	moveq.l	#4,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'キャラクタが0～65535の範囲外です',5,0
    	.even

    color_code_error:
    	moveq.l	#5,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'カラーコードが0～65535の範囲外です',5,0
    	.even

    display_error:
    	moveq.l	#6,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'表示の有無が0～1の範囲外です',5,0
    	.even

    fullpat_error:
    	moveq.l	#7,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'fullpat.xが組み込まれていません',5,0
    	.even

    mode_error_2:
    	moveq.l	#8,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'モードが0～1の範囲外です',5,0
    	.even

    mode_error_4:
    	moveq.l	#9,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'モードが0～3の範囲外です',5,0
    	.even

    offset_error:
    	moveq.l	#10,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'配列のオフセットが範囲外です',5,0
    	.even

    palet_block_error:
    	moveq.l	#11,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'パレットブロックが1～15の範囲外です',5,0
    	.even

    palet_code_error:
    	moveq.l	#12,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'パレットコードが0～15の範囲外です',5,0
    	.even

    pattern_number_error:
    	moveq.l	#13,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'パターン番号が0～511の範囲外です',5,0
    	.even

    pattern_size_error:
    	moveq.l	#14,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'パターンサイズが0～1の範囲外です',5,0
    	.even

    priority_error:
    	moveq.l	#15,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'プライオリティが0～7の範囲外です',5,0
    	.even

    screen_mode_error:
    	moveq.l	#16,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'現在の画面モードではスプライト画面を使用できません',5,0
    	.even

    sprite_number_error:
    	moveq.l	#17,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'スプライト番号が0～127の範囲外です',5,0
    	.even

    text_number_error:
    	moveq.l	#18,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'テキスト番号が0～3の範囲外です',5,0
    	.even

    vdisp_error:
    	moveq.l	#19,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'VDISPの立ち下がりが0～1の範囲外です',5,0
    	.even

    x_error_64:
    	moveq.l	#20,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'X座標が0～63の範囲外です',5,0
    	.even

    x_error_512:
    	moveq.l	#21,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'X座標が0～511の範囲外です',5,0
    	.even

    x_error_1008:
    	moveq.l	#22,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'X座標が-16～1007の範囲外です',5,0
    	.even

    x_error_1024:
    	moveq.l	#23,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'X座標が0～1023の範囲外です',5,0
    	.even

    y_error_64:
    	moveq.l	#24,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'Y座標が0～63の範囲外です',5,0
    	.even

    y_error_512:
    	moveq.l	#25,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'Y座標が0～511の範囲外です',5,0
    	.even

    y_error_1008:
    	moveq.l	#26,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'Y座標が-16～1007の範囲外です',5,0
    	.even

    y_error_1024:
    	moveq.l	#27,d0
    	lea.l	@f(pc),a1
    	goto	error_exit
    @@:	.dc.b	'Y座標が0～511の範囲外です',5,0
    	.even

    ;----------------------------------------------------------------
    	.bss
    	.even

    ;戻り値。voidのときは不要
    return_value:
    	.ds.b	R1_SIZE

STUDIO KAMADA
Copyright © 1999-2026 Makoto Kamada