misc/crtmodfnc.s- Source code ソースコード - XEiJ - STUDIO KAMADA
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

STUDIO KAMADA
Copyright © 1999-2026 Makoto Kamada