misc/crtmodfnc.s
;========================================================================================
; crtmodfnc.s
; Copyright (C) 2003-2025 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 bioswork.equ
.include control2.mac
.include crtc.equ
.include doscall.mac
.include fnc.equ
.include iocscall.mac
.include misc.mac
.include vicon.equ
;----------------------------------------------------------------
; crtmod.fnc (2025-06-29)
;----------------------------------------------------------------
;int crtmod(char mode,[char gon])
; 画面モードを設定します。
; mode 0~ 画面モード
; gon 0~1 グラフィック画面を表示するか
; 戻り値 0 正常終了
; 1 X-BASICのバージョンが違います
; 2 引数が範囲外です
;----------------------------------------------------------------
.text
.even
;インフォメーションテーブル
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:
;CTRL+D(外部関数初期化)ルーチン
ctrld_routine:
;予約
reserved:
rts
;トークンテーブル
token_table:
.dc.b 'crtmod',0
.dc.b 0
.even
;パラメータテーブル
param_table:
.dc.l param_crtmod
;int crtmod(char mode,[char gon])
param_crtmod:
.dc.w P_CHAR ;char mode
.dc.w P_OPT|P_CHAR ;[char gon]
.dc.w R_INT ;int crtmod
;実行アドレステーブル
func_table:
.dc.l func_crtmod
;----------------------------------------------------------------
;int crtmod(char mode,[char gon])
; 画面モードを設定します。
; mode 0~ 画面モード
; gon 0~1 グラフィック画面を表示するか
; 戻り値 0 正常終了
; 1 X-BASICのバージョンが違います
; 2 引数が範囲外です
;----------------------------------------------------------------
;>d0.l:エラーコード
;>a0.l:戻り値
;>a1.l:エラーメッセージ
;?d1-d5/a2-a3
func_crtmod:
;X-BASICのバージョンを確認する
aBAS reg a2 ;basic.xの先頭+$8000
bas reg -$8000(aBAS)
movea.l basic_base(pc),aBAS
if <move.l aBAS,d0>,eq
DOS _GETPDB
movea.l d0,aBAS ;basic.xのプロセス管理ポインタ
adda.l #240+$8000,aBAS ;basic.xの先頭+$8000
move.l aBAS,basic_base
lea.l ($000002)bas,a0 ;識別子
lea.l basic202(pc),a1
moveq.l #1,d0 ;'X-BASICのバージョンが違います'
moveq.l #14/2-1,d1
for d1
goto <cmp.w (a0)+,(a1)+>,ne,error_exit ;識別子が一致しない
next
endif
;引数を受け取る
moveq.l #0,d4
move.b P1_CHAR(sp),d4 ;d4.w=画面モード
if <tst.w P2_TYPE(sp)>,pl
move.b P2_CHAR(sp),d5 ;d5.b=グラフィック画面を表示するか
endif
;引数の範囲を確認する
moveq.l #$FE,d2 ;d2=画面モードの最大値
move.w #$76FF,d1 ;画面モードの最大値の取得を試みる
IOCS _CRTMOD
rol.l #8,d0
if <cmp.b #$16,d0>,eq ;取得できた
ror.l #8,d0
move.b d0,d2 ;画面モードの最大値
endif
moveq.l #2,d0 ;'引数が範囲外です'
goto <cmp.b d2,d4>,hi,error_exit ;画面モードが範囲外
goto <cmp.b #1,d5>,hi,error_exit ;グラフィック画面を表示するかが範囲外
;ファンクション表示を消す
move.w #3,-(sp) ;普通の行
move.w #14,-(sp) ;ファンクション表示行のモードの取得と設定
DOS _CONCTRL
addq.l #4,sp
;画面モードを設定する
move.w d4,d1
IOCS _CRTMOD
;グラフィック画面を表示する
if <tst.b d5>,ne
IOCS _G_CLR_ON
endif
;basic.xのワークエリアを設定する
moveq.l #-1,d1
moveq.l #-1,d2
IOCS _B_CONSOL
move.w d2,d3 ;d3.w=行数-1
swap.w d2 ;d2.w=桁数-1
move.w #-1,($00A13A)bas ;screenの画面モード番号。サイズ<<3|実画面と色数<<1|解像度。-1=未設定
clr.w ($00A13C)bas ;最上行Y座標
move.w d3,($00A13E)bas ;最下行Y座標
clr.w ($00A140)bas ;ファンクション表示行の有無
addq.w #1,d2 ;d2.w=桁数
addq.w #1,d3 ;d3.w=行数
move.w d2,($00918E)bas ;画面の桁数
move.w d3,($009190)bas ;画面の行数
addq.w #1,d2 ;d2.w=桁数+1
add.w d2,d2 ;d2.w=2*(桁数+1)
ext.l d2 ;d2.l=2*(桁数+1)
move.l d2,($009192)bas ;テキスト画面バッファのY方向のオフセット
move.l #text_buffer,($009196)bas ;テキスト画面バッファの先頭アドレス
;テキスト画面バッファを初期化する
jsr ($00625E)bas ;CTRL+L CLR テキスト画面を消去する
;戻り値は0
moveq.l #0,d0
;正常終了
;<d0.l:戻り値
normal_exit:
lea.l return_value(pc),a0 ;戻り値。voidのときは不要
move.l d0,R1_INT(a0) ;戻り値
moveq.l #0,d0 ;終了コードは0。エラーメッセージは不要
rts
;エラー終了
;<d0.l:エラーコード。0以外。負はDOSコールエラー
error_exit:
lea.l return_value(pc),a0 ;戻り値。voidのときは不要
move.l d0,R1_INT(a0) ;error offのときの戻り値。エラーコード
lea.l error_message(pc),a1 ;エラーメッセージ。DOSコールエラーのときは不要
move.w d0,d1
subq.w #2,d1
if pl
for d1
do
tst.b (a1)+
while ne
next
endif
rts
;エラーメッセージ
error_message:
.dc.b 'X-BASICのバージョンが違います',0 ;1
.dc.b '引数が範囲外です',0 ;2
.even
;識別子
basic202:
.dc.b 'V2.02-8906 '
.bss
.even
;戻り値。voidのときは不要
return_value:
.ds.b R1_SIZE
;basic.xの先頭+$8000
basic_base:
.ds.l 1
;テキスト画面バッファ
; basic.xのバッファは96桁32行を超えられないので新しく確保する
text_buffer:
.ds.w (128+1)*64