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