misc/crtmod16.s
;========================================================================================
; crtmod16.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 dosconst.equ
.include doswork.equ
.include iocscall.mac
.include mfp.equ
.include misc.mac
.include push2.mac
.include sprc.equ
.include sram.equ
.include sysport.equ
.include vicon.equ
;----------------------------------------------------------------
; crtmod16.x (2025-06-29)
;
; 説明
; crtmod16.xはIPLROM 1.6に含まれるCRTMOD/G_CLR_ONを常駐プログラムにしたものです。
; 一般的な液晶モニタで768x512ドットの画面をはみ出さないように表示できます。
; 384x256ドット、512x512ドット(正方形)などの画面モードが追加されます。
;
; 補足
; IPLROM 1.0~1.3にあったグラフィックパレットに関するバグが修正されます。
; バグに依存しているソフトウェアが誤動作する場合はcrtmrb16.xを組み込んでください。
;
; オプション
; -e 常駐します。
; -l 0~1 0でCRT向けの同期周波数、1でLCD向けの同期周波数を選択します。
; -m 0~73 画面モードを選択します。crtmodtest.xを参照してください。
; -r 常駐を解除します。
;
; 更新履歴
; 2022-02-19
; IPLROM 1.6の_CRTMODと_G_CLR_ONを抜き出したもの
; IPLROM 1.0~1.3のバグを修正
; CRT向けとLCD向けを選択できる
; 28~39を追加。384x256、512x512(正方形)、256x256(正方形)
; 2022-02-21
; crtmod16.xを公開
; 2022-06-08
; 2023-01-10
; 2023-10-12
; $56FFを追加。バージョンを返す
; 2023-11-15
; $16FFを追加。CRTorLCDとバージョンを返す
; 2024-03-13
; crtmrb16.xを追加。IPLROM 1.0~1.3のバグを再現する。バグに依存しているソフトウェアを修正できないときの救済策
; 2024-08-25
; 40~47を追加。512x256、512x256(スプライトは512x512)
; 2025-03-23
; $00ED0095が$6xでないとき$60を書き込む。実機でSRAMが壊れているとき予期せずLCDモードになってしまうことがある問題の対策
; 2025-04-19
; stouを修正。Thanks TcbnErik
; 2025-06-29
; 48~73を追加。拡張グラフィック画面に対応
; $76FFを追加。$16000000+画面モードの最大値を返す
; $xxFFを除いて設定後の画面モードが範囲外のとき-1を返す
; 拡張グラフィック画面がないのに拡張グラフィック画面が必要な画面モードが指定されたとき-2を返す
;
;----------------------------------------------------------------
;IOCSコール$10 _CRTMOD 画面モードの取得と設定
;<d1.w:設定後の画面モード
; $16FF バージョンの確認。$16xxxxxx(CRT向け)または$96xxxxxx(LCD向け)を返す
; $56FF バージョンの確認。$16xxxxxxを返す
; $76FF 画面モードの最大値の確認。$160000xxを返す
; $43xx CRT向け。SRAMに保存する。$43FFはSRAMの変更のみ
; $4Cxx LCD向け。SRAMに保存する。$4CFFはSRAMの変更のみ
; $xxFF 取得のみ
; $01xx 初期化しない
;>d0.l:設定前の画面モード。-1=設定後の画面モードが範囲外,-2=拡張グラフィック画面がない
; バージョンの確認のとき$16xxxxxxまたは$96xxxxxx
; 画面モードの最大値の確認のとき$160000xx
;----------------------------------------------------------------
;IOCSコール$90 _G_CLR_ON グラフィック画面の消去とパレット初期化と表示ON
;>d0.l:0
;----------------------------------------------------------------
DEVICE_NAME reg 'CRTM16*/'
.ifdef CRTMOD_REPRODUCE_BUG ;バグを再現させる
TITLE_STRING reg 'crtmrb16.x (2025-06-29)'
.else
TITLE_STRING reg 'crtmod16.x (2025-06-29)'
.endif
CRTMOD_VERSION equ $16250629 ;_CRTMODのバージョン
PATCH_jsr .macro name,label
bsr label
.endm
;----------------------------------------------------------------
;プログラムの先頭
.text
program_head:
;デバイスヘッダ
.dc.l -1 ;次のデバイスヘッダ。-1=デバイスヘッダのリストの末尾
.dc.w $8000 ;デバイスタイプ。キャラクタデバイス
.dc.l strategy_routine ;ストラテジルーチン
.dc.l interrupt_routine ;インタラプトルーチン
.dc.b DEVICE_NAME ;デバイス名
;----------------------------------------------------------------
;リクエストヘッダのアドレス
request_header:
.dc.l 0
;ベクタテーブル
vector_table:
.dc.w 4*($100+_CRTMOD) ;オフセット
.dc.l iocs_10_CRTMOD ;新しいベクタ
.dc.l 0 ;古いベクタ
.dc.w 4*($100+_G_CLR_ON)
.dc.l iocs_90_G_CLR_ON
.dc.l 0
.dc.w 0
;----------------------------------------------------------------
;ストラテジルーチン
strategy_routine:
move.l a5,request_header
rts
;インタラプトルーチン
interrupt_routine:
push d0-d7/a0-a6
movea.l request_header(pc),a5
moveq.l #0,d0
move.b 2(a5),d0 ;コマンド番号
if <cmp.w #(jump_table_end-jump_table)/2,d0>,hs ;範囲外
moveq.l #(jump_table_end-jump_table)/2,d0
endif
add.w d0,d0
move.w jump_table(pc,d0.w),d0
jsr jump_table(pc,d0.w)
move.b d0,3(a5) ;エラーコード下位
lsr.w #8,d0
move.b d0,4(a5) ;エラーコード上位
pop
rts
;デバイスコマンドのジャンプテーブル
jump_table:
.dc.w initialize-jump_table ;デバイスコマンド0 初期化
.dc.w command_error-jump_table ;デバイスコマンド1 ディスク交換チェック
.dc.w command_error-jump_table ;デバイスコマンド2 BPBテーブルの再構築
.dc.w ioctrl_input-jump_table ;デバイスコマンド3 _IOCTRLによる入力
.dc.w input-jump_table ;デバイスコマンド4 入力
.dc.w control_sense-jump_table ;デバイスコマンド5 コントロール/センス
.dc.w input_status-jump_table ;デバイスコマンド6 入力ステータス
.dc.w input_flush-jump_table ;デバイスコマンド7 入力バッファフラッシュ
.dc.w output-jump_table ;デバイスコマンド8 出力(ベリファイなし)
.dc.w output-jump_table ;デバイスコマンド9 出力(ベリファイあり)
.dc.w output_status-jump_table ;デバイスコマンド10 出力ステータス
.dc.w no_error-jump_table ;デバイスコマンド11 正常終了
.dc.w ioctrl_output-jump_table ;デバイスコマンド12 _IOCTRLによる出力
jump_table_end:
.dc.w command_error-jump_table ;範囲外 コマンドエラー
;デバイスコマンド1 ディスク交換チェック
;デバイスコマンド2 BPBテーブルの再構築
;コマンドエラー
command_error:
move.w #IGNORE|ABORT|UNKNOWN_COMMAND,d0 ;無視(I) 中止(A) デバイスドライバに無効なコマンドを指定しました
rts
;デバイスコマンド3 _IOCTRLによる入力
ioctrl_input:
; movea.l 14(a5),a1 ;アドレス
goto command_error
;デバイスコマンド4 入力
input:
movea.l 14(a5),a1 ;アドレス
move.l 18(a5),d3 ;長さ
docontinue
clr.b (a1)+
while <subq.l #1,d3>,cc
moveq.l #0,d0 ;常に成功する(終わるまで復帰しない)
rts
;デバイスコマンド5 コントロール/センス
control_sense:
clr.b 13(a5) ;データ
moveq.l #0,d0 ;常に成功する
rts
;デバイスコマンド6 入力ステータス
input_status:
moveq.l #1,d0 ;0=入力バッファが空ではないので入力できる,1=入力バッファが空なので入力できない
rts
;デバイスコマンド7 入力バッファフラッシュ
input_flush:
moveq.l #0,d0 ;常に成功する
rts
;デバイスコマンド8 出力(ベリファイなし)
;デバイスコマンド9 出力(ベリファイあり)
output:
; movea.l 14(a5),a1 ;アドレス
; move.l 18(a5),d3 ;長さ
moveq.l #0,d0 ;常に成功する(終わるまで復帰しない)
rts
;デバイスコマンド10 出力ステータス
output_status:
moveq.l #1,d0 ;0=出力バッファが満杯ではないので出力できる,1=出力バッファが満杯なので出力できない
rts
;デバイスコマンド11 正常終了
no_error:
moveq.l #0,d0 ;常に成功する
rts
;デバイスコマンド12 _IOCTRLによる出力
ioctrl_output:
; movea.l 14(a5),a1 ;アドレス
goto command_error
;----------------------------------------------------------------
;IOCSコール$10 _CRTMOD 画面モードの取得と設定
;<d1.w:設定後の画面モード
; $16FF バージョンの確認。$16xxxxxx(CRT向け)または$96xxxxxx(LCD向け)を返す
; $56FF バージョンの確認。$16xxxxxxを返す
; $76FF 画面モードの最大値の確認。$160000xxを返す
; $43xx CRT向け。SRAMに保存する。$43FFはSRAMの変更のみ
; $4Cxx LCD向け。SRAMに保存する。$4CFFはSRAMの変更のみ
; $xxFF 取得のみ
; $01xx 初期化しない
;>d0.l:設定前の画面モード。-1=設定後の画面モードが範囲外,-2=拡張グラフィック画面がない
; バージョンの確認のとき$16xxxxxxまたは$96xxxxxx
; 画面モードの最大値の確認のとき$160000xx
;----------------------------------------------------------------
; 画面モード
;
; 画面モード 解像度 画面サイズ 実画面サイズ 色数 ページ数
; 0 高 512x512 1024x1024 16 1
; 1 低 512x512 1024x1024 16 1
; 2 高 256x256 1024x1024 16 1
; 3 低 256x256 1024x1024 16 1
; 4 高 512x512 512x512 16 4
; 5 低 512x512 512x512 16 4
; 6 高 256x256 512x512 16 4
; 7 低 256x256 512x512 16 4
; 8 高 512x512 512x512 256 2
; 9 低 512x512 512x512 256 2
; 10 高 256x256 512x512 256 2
; 11 低 256x256 512x512 256 2
; 12 高 512x512 512x512 65536 1
; 13 低 512x512 512x512 65536 1
; 14 高 256x256 512x512 65536 1
; 15 低 256x256 512x512 65536 1
; 16 高 768x512 1024x1024 16 1
; 17 中 1024x424 1024x1024 16 1
; 18 中 1024x848 1024x1024 16 1
; 19 VGA 640x480 1024x1024 16 1
; 20 高 768x512 512x512 256 2
; 21 中 1024x424 512x512 256 2
; 22 中 1024x848 512x512 256 2
; 23 VGA 640x480 512x512 256 2
; 24 高 768x512 512x512 65536 1
; 25 中 1024x424 512x512 65536 1
; 26 中 1024x848 512x512 65536 1
; 27 VGA 640x480 512x512 65536 1
; $100+(0~27) 初期化しない
; -1 取得のみ
;
; 以下は拡張
; 28 高 384x256 1024x1024 16 1
; 29 高 384x256 512x512 16 4
; 30 高 384x256 512x512 256 2
; 31 高 384x256 512x512 65536 1
; 32 高 512x512(正方形) 1024x1024 16 1
; 33 高 512x512(正方形) 512x512 16 4
; 34 高 512x512(正方形) 512x512 256 2
; 35 高 512x512(正方形) 512x512 65536 1
; 36 高 256x256(正方形) 1024x1024 16 1
; 37 高 256x256(正方形) 512x512 16 4
; 38 高 256x256(正方形) 512x512 256 2
; 39 高 256x256(正方形) 512x512 65536 1
; 40 高 512x256 1024x1024 16 1
; 41 高 512x256 512x512 16 4
; 42 高 512x256 512x512 256 2
; 43 高 512x256 512x512 65536 1
; 44 高 512x256(※) 1024x1024 16 1
; 45 高 512x256(※) 512x512 16 4
; 46 高 512x256(※) 512x512 256 2
; 47 高 512x256(※) 512x512 65536 1
; ※スプライトは512x512
;
; 以下は拡張グラフィック画面が必要
; 0,1,2,3,16,17,18,19,28,32,36,40,44を256色にしたもの
; 48 高 512x512 1024x1024 256 1
; 49 低 512x512 1024x1024 256 1
; 50 高 256x256 1024x1024 256 1
; 51 低 256x256 1024x1024 256 1
; 52 高 768x512 1024x1024 256 1
; 53 中 1024x424 1024x1024 256 1
; 54 中 1024x848 1024x1024 256 1
; 55 VGA 640x480 1024x1024 256 1
; 56 高 384x256 1024x1024 256 1
; 57 高 512x512(正方形) 1024x1024 256 1
; 58 高 256x256(正方形) 1024x1024 256 1
; 59 高 512x256 1024x1024 256 1
; 60 高 512x256(※) 1024x1024 256 1
; 0,1,2,3,16,17,18,19,28,32,36,40,44を65536色にしたもの
; 61 高 512x512 1024x1024 65536 1
; 62 低 512x512 1024x1024 65536 1
; 63 高 256x256 1024x1024 65536 1
; 64 低 256x256 1024x1024 65536 1
; 65 高 768x512 1024x1024 65536 1
; 66 中 1024x424 1024x1024 65536 1
; 67 中 1024x848 1024x1024 65536 1
; 68 VGA 640x480 1024x1024 65536 1
; 69 高 384x256 1024x1024 65536 1
; 70 高 512x512(正方形) 1024x1024 65536 1
; 71 高 256x256(正方形) 1024x1024 65536 1
; 72 高 512x256 1024x1024 65536 1
; 73 高 512x256(※) 1024x1024 65536 1
;
;----------------------------------------------------------------
; いろいろ
;
; CRT向けとLCD向け
; 各画面モードの同期周波数をそれぞれCRT向けとLCD向けに分ける
; SRAM_XEIJのSRAM_XEIJ_LCD_BITが0のときCRT向け、1のときLCD向けの同期周波数で出力する
;
; 画面モード17
; 水平24.699kHz、垂直53.116Hz、1024x424、実画面1024x1024、16色
; X68000初代からあるが未公開
; LCD向けのときは画面モード16の上下を削る
;
; 画面モード18
; 水平24.699kHz、垂直53.116Hz、1024x848(インターレース)、実画面1024x1024、16色
; X68000初代からあるが未公開
; LCD向けのときは画面モード16の上下を削ってインターレースにする
;
; 画面モード19(VGAモード)
; 水平31.469kHz、垂直59.940Hz、640x480、実画面1024x1024、16色
; X68000 Compactで追加された
; CRT向けのときは画面モード16の周囲を削る
; LCD向けのときはそのまま
;
; 画面モード20~23
; 画面モード16~19を実画面512x512、256色に変更したもの
; X68030で追加された。未公開
;
; 画面モード24~27
; 画面モード16~19を実画面512x512、65536色に変更したもの
; X68030で追加された。未公開
;
; グラフィックパレットのバグ(IPLROM 1.0~1.3)
; _CRTMODが指定された画面モードと異なる色数でグラフィックパレットを初期化する
; https://stdkmd.net/bugsx68k/#rom_crtmod_gpalet
; 256x256は16色、512x512は256色、それ以外は65536色になる
;
; 画面モード20~27のバグ(IPLROM 1.3)
; 画面モードに20~27が指定されたとき画面モードを16~19にしてから256色または65536色に変更しているが、
; このときBIOSワークエリアの画面モードを16~19のまま放置している
; 続けて_G_CLR_ONを呼び出すと画面モードが16~19なので16色に戻ってしまう
;
; クリッピングエリアのバグ(IPLROM 1.3)
; _CRTMODで画面モードを22または26にするとクリッピングエリアが512x848になる
;
; VGAオシレータの問題
; 初代~XVIにはVGAオシレータがないのでVGAモードが正しい同期周波数で出力されない
; VGAオシレータがある場合
; (50.350MHz/2)/(8*100)=31.469kHz
; (50.350MHz/2)/(8*100*525)=59.940Hz
; VGAオシレータがない場合
; (69.552MHz/3)/(8*100)=28.980kHz
; (69.552MHz/3)/(8*100*525)=55.200Hz
; 大きく外れるわけではないのでマルチスキャンモニタは追従できるが気持ち悪い
;
; VGAオシレータの有無の判別
; VGAモードの垂直周期はVGAオシレータがあるとき16.683ms、ないとき18.116ms
; 垂直同期割り込みの間にTimer-Cが1周10msと7.5ms進んだかどうかでVGAオシレータの有無を判別できるはず
; 後で試す?
;
;----------------------------------------------------------------
; 同期信号とCRTC設定値の関係
;
; HT 水平周期カラム数
; HS 水平同期パルスカラム数
; HB 水平バックポーチカラム数
; HD 水平映像期間カラム数
; HF 水平フロントポーチカラム数
; VT 垂直周期ラスタ数
; VS 垂直同期パルスラスタ数
; VB 垂直バックポーチラスタ数
; VD 垂直映像期間ラスタ数
; VF 垂直フロントポーチラスタ数
;
; R00 HT-1=HS+HB+HD+HF-1 水平フロントポーチ終了カラム
; R01 HS-1 水平同期パルス終了カラム
; R02 HS+HB-5 水平バックポーチ終了カラム-4
; R03 HS+HB+HD-5 水平映像期間終了カラム-4
; R04 VT-1=VS+VB+VD+VF-1 垂直フロントポーチ終了ラスタ
; R05 VS-1 垂直同期パルス終了ラスタ
; R06 VS+VB-1 垂直バックポーチ終了ラスタ
; R07 VS+VB+VD-1 垂直映像期間終了ラスタ
;
;----------------------------------------------------------------
; オシレータと分周比とR20LとHRLの関係
;
; OSC/DIV R20L HRL
; 38/8 %0**00 *
; 38/4 %0**01 *
; 38/8 %0**1* *
; 69/6 %1**00 0
; 69/8 %1**00 1
; 69/3 %1**01 0
; 69/4 %1**01 1
; 69/2 %1**10 * スプライト不可
; 50/2 %1**11 * スプライト不可。Compactから
;
;----------------------------------------------------------------
; CRTC設定値(CRT向け)
;
; CRT 0/4/8/12/48/61: 512x512 31.500kHz 55.458Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10101 0 91 9 17 81 567 5 40 552 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 3 92 10 12 64 6 568 6 35 512 15 |
; +------------------------------------------------------+
; (69.552MHz/3)/(8*92)=31.500kHz (69.552MHz/3)/(8*92*568)=55.458Hz
; 64/92=0.696 512/568=0.901 (0.696/0.901)/(512/512)=0.772
; 31k
;
; CRT 1/5/9/13/49/62: 512x512 15.980kHz 61.463Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %00101 0 75 3 5 69 259 2 16 256 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 38.864 4 76 4 6 64 2 260 3 14 240 3 |
; +------------------------------------------------------+
; (38.864MHz/4)/(8*76)=15.980kHz (38.864MHz/4)/(8*76*260)=61.463Hz
; 64/76=0.842 240/260=0.923 (0.842/0.923)/(512/512)=0.912
; 15k インターレース
;
; CRT 2/6/10/14/50/63: 256x256 31.500kHz 55.458Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10000 0 45 4 6 38 567 5 40 552 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 6 46 5 6 32 3 568 6 35 512 15 |
; +------------------------------------------------------+
; (69.552MHz/6)/(8*46)=31.500kHz (69.552MHz/6)/(8*46*568)=55.458Hz
; 32/46=0.696 512/568=0.901 (0.696/0.901)/(256/256)=0.772
; 31k ラスタ2度読み
;
; CRT 3/7/11/15/51/64: 256x256 15.980kHz 61.463Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %00000 0 37 1 0 32 259 2 16 256 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 38.864 8 38 2 3 32 1 260 3 14 240 3 |
; +------------------------------------------------------+
; (38.864MHz/8)/(8*38)=15.980kHz (38.864MHz/8)/(8*38*260)=61.463Hz
; 32/38=0.842 240/260=0.923 (0.842/0.923)/(256/256)=0.912
; 15k
;
; CRT 16/20/24/52/65: 768x512 31.500kHz 55.458Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10110 0 137 14 28 124 567 5 40 552 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 2 138 15 18 96 9 568 6 35 512 15 |
; +------------------------------------------------------+
; (69.552MHz/2)/(8*138)=31.500kHz (69.552MHz/2)/(8*138*568)=55.458Hz
; 96/138=0.696 512/568=0.901 (0.696/0.901)/(768/512)=0.514
; 31k
;
; CRT 17/21/25/53/66: 1024x424 24.699kHz 53.116Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10110 0 175 15 31 159 464 7 32 456 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 2 176 16 20 128 12 465 8 25 424 8 |
; +------------------------------------------------------+
; (69.552MHz/2)/(8*176)=24.699kHz (69.552MHz/2)/(8*176*465)=53.116Hz
; 128/176=0.727 424/465=0.912 (0.727/0.912)/(1024/424)=0.330
; 24k
;
; CRT 18/22/26/54/67: 1024x848 24.699kHz 53.116Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %11010 0 175 15 31 159 464 7 32 456 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 2 176 16 20 128 12 465 8 25 424 8 |
; +------------------------------------------------------+
; (69.552MHz/2)/(8*176)=24.699kHz (69.552MHz/2)/(8*176*465)=53.116Hz
; 128/176=0.727 424/465=0.912 (0.727/0.912)/(1024/848)=0.661
; 24k インターレース
;
; CRT 19/23/27/55/68: 640x480 31.500kHz 55.458Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10110 0 137 14 36 116 567 5 56 536 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 2 138 15 26 80 17 568 6 51 480 31 |
; +------------------------------------------------------+
; (69.552MHz/2)/(8*138)=31.500kHz (69.552MHz/2)/(8*138*568)=55.458Hz
; 80/138=0.580 480/568=0.845 (0.580/0.845)/(640/480)=0.514
; 31k
;
; CRT 28/29/30/31/56/69: 384x256 31.963kHz 56.273Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10001 1 67 6 11 59 567 5 40 552 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 4 68 7 9 48 4 568 6 35 512 15 |
; +------------------------------------------------------+
; (69.552MHz/4)/(8*68)=31.963kHz (69.552MHz/4)/(8*68*568)=56.273Hz
; 48/68=0.706 512/568=0.901 (0.706/0.901)/(384/256)=0.522
; 31k ラスタ2度読み
;
; CRT 32/33/34/35/57/70: 512x512 31.500kHz 55.458Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10110 0 137 14 44 108 567 5 40 552 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 2 138 15 34 64 25 568 6 35 512 15 |
; +------------------------------------------------------+
; (69.552MHz/2)/(8*138)=31.500kHz (69.552MHz/2)/(8*138*568)=55.458Hz
; 64/138=0.464 512/568=0.901 (0.464/0.901)/(512/512)=0.514
; 31k
;
; CRT 36/37/38/39/58/71: 256x256 31.963kHz 56.273Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10001 1 67 6 19 51 567 5 40 552 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 4 68 7 17 32 12 568 6 35 512 15 |
; +------------------------------------------------------+
; (69.552MHz/4)/(8*68)=31.963kHz (69.552MHz/4)/(8*68*568)=56.273Hz
; 32/68=0.471 512/568=0.901 (0.471/0.901)/(256/256)=0.522
; 31k ラスタ2度読み
;
; CRT 40/41/42/43/44/45/46/47/59/60/72/73: 512x256 31.500kHz 55.458Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10001 0 91 9 17 81 567 5 40 552 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 3 92 10 12 64 6 568 6 35 512 15 |
; +------------------------------------------------------+
; (69.552MHz/3)/(8*92)=31.500kHz (69.552MHz/3)/(8*92*568)=55.458Hz
; 64/92=0.696 512/568=0.901 (0.696/0.901)/(512/256)=0.386
; 31k
;
;----------------------------------------------------------------
; CRTC設定値(LCD向け)
;
; LCD 0/4/8/12/48/61: 512x512 35.341kHz 56.546Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10101 0 81 5 11 75 624 1 67 579 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 3 82 6 10 64 2 625 2 66 512 45 |
; +------------------------------------------------------+
; (69.552MHz/3)/(8*82)=35.341kHz (69.552MHz/3)/(8*82*625)=56.546Hz
; 64/82=0.780 512/625=0.819 (0.780/0.819)/(512/512)=0.953
; SVGA
;
; LCD 1/5/9/13/49/62: 512x512 35.341kHz 56.546Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10101 0 81 5 11 75 624 1 83 563 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 3 82 6 10 64 2 625 2 82 480 61 |
; +------------------------------------------------------+
; (69.552MHz/3)/(8*82)=35.341kHz (69.552MHz/3)/(8*82*625)=56.546Hz
; 64/82=0.780 480/625=0.768 (0.780/0.768)/(512/512)=1.016
; SVGA
;
; LCD 2/6/10/14/50/63: 256x256 34.500kHz 55.200Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10000 0 41 2 3 35 624 1 67 579 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 6 42 3 5 32 2 625 2 66 512 45 |
; +------------------------------------------------------+
; (69.552MHz/6)/(8*42)=34.500kHz (69.552MHz/6)/(8*42*625)=55.200Hz
; 32/42=0.762 512/625=0.819 (0.762/0.819)/(256/256)=0.930
; SVGA ラスタ2度読み
;
; LCD 3/7/11/15/51/64: 256x256 34.500kHz 55.200Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10000 0 41 2 3 35 624 1 83 563 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 6 42 3 5 32 2 625 2 82 480 61 |
; +------------------------------------------------------+
; (69.552MHz/6)/(8*42)=34.500kHz (69.552MHz/6)/(8*42*625)=55.200Hz
; 32/42=0.762 480/625=0.768 (0.762/0.768)/(256/256)=0.992
; SVGA ラスタ2度読み
;
; LCD 16/20/24/52/65: 768x512 35.056kHz 56.090Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10110 0 123 8 19 115 624 1 67 579 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 2 124 9 15 96 4 625 2 66 512 45 |
; +------------------------------------------------------+
; (69.552MHz/2)/(8*124)=35.056kHz (69.552MHz/2)/(8*124*625)=56.090Hz
; 96/124=0.774 512/625=0.819 (0.774/0.819)/(768/512)=0.630
; SVGA
;
; LCD 17/21/25/53/66: 768x600 35.056kHz 56.090Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10110 0 123 8 19 115 624 1 23 623 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 2 124 9 15 96 4 625 2 22 600 1 |
; +------------------------------------------------------+
; (69.552MHz/2)/(8*124)=35.056kHz (69.552MHz/2)/(8*124*625)=56.090Hz
; 96/124=0.774 600/625=0.960 (0.774/0.960)/(768/600)=0.630
; SVGA
;
; LCD 18/22/26/54/67: 768x1024 35.056kHz 56.090Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %11010 0 123 8 19 115 624 1 67 579 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 2 124 9 15 96 4 625 2 66 512 45 |
; +------------------------------------------------------+
; (69.552MHz/2)/(8*124)=35.056kHz (69.552MHz/2)/(8*124*625)=56.090Hz
; 96/124=0.774 512/625=0.819 (0.774/0.819)/(768/1024)=1.260
; SVGA インターレース
;
; LCD 19/23/27/55/68: 640x480 31.469kHz 59.940Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10111 0 99 11 13 93 524 1 34 514 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 50.350 2 100 12 6 80 2 525 2 33 480 10 |
; +------------------------------------------------------+
; (50.350MHz/2)/(8*100)=31.469kHz (50.350MHz/2)/(8*100*525)=59.940Hz
; 80/100=0.800 480/525=0.914 (0.800/0.914)/(640/480)=0.656
; VGA
;
; LCD 28/29/30/31/56/69: 384x256 31.963kHz 51.141Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10001 1 67 6 11 59 624 1 67 579 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 4 68 7 9 48 4 625 2 66 512 45 |
; +------------------------------------------------------+
; (69.552MHz/4)/(8*68)=31.963kHz (69.552MHz/4)/(8*68*625)=51.141Hz
; 48/68=0.706 512/625=0.819 (0.706/0.819)/(384/256)=0.574
; ラスタ2度読み
;
; LCD 32/33/34/35/57/70: 512x512 35.056kHz 56.090Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10110 0 123 8 35 99 624 1 67 579 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 2 124 9 31 64 20 625 2 66 512 45 |
; +------------------------------------------------------+
; (69.552MHz/2)/(8*124)=35.056kHz (69.552MHz/2)/(8*124*625)=56.090Hz
; 64/124=0.516 512/625=0.819 (0.516/0.819)/(512/512)=0.630
; SVGA
;
; LCD 36/37/38/39/58/71: 256x256 31.963kHz 51.141Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10001 1 67 6 19 51 624 1 67 579 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 4 68 7 17 32 12 625 2 66 512 45 |
; +------------------------------------------------------+
; (69.552MHz/4)/(8*68)=31.963kHz (69.552MHz/4)/(8*68*625)=51.141Hz
; 32/68=0.471 512/625=0.819 (0.471/0.819)/(256/256)=0.574
; ラスタ2度読み
;
; LCD 40/41/42/43/44/45/46/47/59/60/72/73: 512x256 35.341kHz 56.546Hz
; +------------------------------------------------------+
; | R20L HRL R00 R01 R02 R03 R04 R05 R06 R07 |
; | %10001 0 81 5 11 75 624 1 67 579 |
; +------------------------------------------------------+
; | OSC DIV HT HS HB HD HF VT VS VB VD VF |
; | 69.552 3 82 6 10 64 2 625 2 66 512 45 |
; +------------------------------------------------------+
; (69.552MHz/3)/(8*82)=35.341kHz (69.552MHz/3)/(8*82*625)=56.546Hz
; 64/82=0.780 512/625=0.819 (0.780/0.819)/(512/256)=0.476
; SVGA
;
; 【参考】VGA: 640x480 31.469kHz 59.940Hz
; +------------------------------------------------------+
; | OSC HT HS HB HD HF VT VS VB VD VF |
; | 25.175 100 12 6 80 2 525 2 33 480 10 |
; +------------------------------------------------------+
; 25.175MHz/(8*100)=31.469kHz (25.175MHz/1)/(8*100*525)=59.940Hz
; 80/100=0.800 480/525=0.914 (0.800/0.914)/(640/480)=0.656
;
; 【参考】SVGA: 800x600 35.156kHz 56.250Hz
; +------------------------------------------------------+
; | OSC HT HS HB HD HF VT VS VB VD VF |
; | 36.000 128 9 16 100 3 625 2 22 600 1 |
; +------------------------------------------------------+
; 36.000MHz/(8*128)=35.156kHz (36.000MHz/1)/(8*128*625)=56.250Hz
; 100/128=0.781 600/625=0.960 (0.781/0.960)/(800/600)=0.610
;
; 【参考】SVGA: 800x600 37.879kHz 60.317Hz
; +------------------------------------------------------+
; | OSC HT HS HB HD HF VT VS VB VD VF |
; | 40.000 132 16 11 100 5 628 4 23 600 1 |
; +------------------------------------------------------+
; 40.000MHz/(8*132)=37.879kHz (40.000MHz/1)/(8*132*628)=60.317Hz
; 100/132=0.758 600/628=0.955 (0.758/0.955)/(800/600)=0.595
;
; 【参考】SVGA: 800x600 46.875kHz 75.000Hz
; +------------------------------------------------------+
; | OSC HT HS HB HD HF VT VS VB VD VF |
; | 49.500 132 10 20 100 2 625 3 21 600 1 |
; +------------------------------------------------------+
; 49.500MHz/(8*132)=46.875kHz (49.500MHz/1)/(8*132*625)=75.000Hz
; 100/132=0.758 600/625=0.960 (0.758/0.960)/(800/600)=0.592
;
;----------------------------------------------------------------
;パラメータ1
.offset 0
crtmod_param_1_width: .ds.w 1
crtmod_param_1_height: .ds.w 1
crtmod_param_1_r20h: .ds.b 1
.ds.b 1
crtmod_param_1_2nd: .ds.w 1
crtmod_param_1_size:
.text
;パラメータ2
.offset 0
crtmod_param_2_r20l: .ds.b 1
crtmod_param_2_hrl: .ds.b 1
crtmod_param_2_r00: .ds.w 1
crtmod_param_2_r01: .ds.w 1
crtmod_param_2_r02: .ds.w 1
crtmod_param_2_r03: .ds.w 1
crtmod_param_2_r04: .ds.w 1
crtmod_param_2_r05: .ds.w 1
crtmod_param_2_r06: .ds.w 1
crtmod_param_2_r07: .ds.w 1
crtmod_param_2_r08: .ds.w 1
crtmod_param_2_size:
.text
crtmod_param_1 .macro width,height,r20h,offset2nd
.dc.w width
.dc.w height
.dc.b r20h ;R20H
.dc.b 0
.dc.w crtmod_param_2_size*offset2nd
.endm
crtmod_param_2 .macro r20l,hrl,ht,hs,hb,hd,hf,vt,vs,vb,vd,vf,r08
.fail (ht.and.1)!=0
.fail ht!=hs+hb+hd+hf
.fail vt!=vs+vb+vd+vf
.dc.b r20l ;R20L
.dc.b hrl ;HRL
.dc.w hs+hb+hd+hf-1 ;R00
.dc.w hs-1 ;R01
.dc.w hs+hb-5 ;R02
.dc.w hs+hb+hd-5 ;R03
.dc.w vs+vb+vd+vf-1 ;R04
.dc.w vs-1 ;R05
.dc.w vs+vb-1 ;R06
.dc.w vs+vb+vd-1 ;R07
.dc.w r08 ;R08
.endm
crtmod_modes equ (crtmod_table_1_crt_end-crtmod_table_1_crt)/crtmod_param_1_size ;画面モードの数
iocs_10_CRTMOD:
dMM reg d3 ;メモリモード
dPM reg d4 ;設定前の画面モード
dGVRAM reg d5 ;$00C00000
aE8 reg a2 ;(~)E8のベースアドレス
aEB reg a3 ;(~)EBのベースアドレス
aED reg a4 ;(~)EDのベースアドレス
aP1 reg a5 ;パラメータ1のアドレス
aP2 reg a6 ;パラメータ2のアドレス
push d1-d2/dMM/dPM/dGVRAM/a0-a1/aE8/aEB/aED/aP1/aP2
move.l #$00C00000,dGVRAM
;(~)E8でアクセスする
; $00E80000 CRTC
; $00E82000 VICON
; $00E84000 DMAC
; $00E86000 SUPERAREA
; $00E88000 MFP
; $00E8A000 RTC
; $00E8C000 PRNPORT
; $00E8E000 SYSPORT
lea.l $00E88000,aE8
E8 reg -$00E88000(aE8)
;(~)EBでアクセスする
; $00EB0000 SPRC
lea.l $00EB8000,aEB
EB reg -$00EB8000(aEB)
;(~)EDでアクセスする
; $00ED0000 SRAM
lea.l $00ED8000,aED
ED reg -$00ED8000(aED)
;SRAMを初期化する
moveq.l #$60,d0
moveq.l #$F0,d2
and.b (SRAM_XEIJ)ED,d2
if <cmp.b d0,d2>,ne ;初期化されていない
move.b #$31,(SYSPORT_SRAM)E8 ;unlocksram
move.b d0,(SRAM_XEIJ)ED ;初期化する
clr.b (SYSPORT_SRAM)E8 ;locksram
endif
;バージョンの確認
move.l #CRTMOD_VERSION,d0
goto <cmp.w #$56FF,d1>,eq,@f
if <cmp.w #$16FF,d1>,eq
if <btst.b #SRAM_XEIJ_LCD_BIT,(SRAM_XEIJ)ED>,ne
bset.l #31,d0
endif
@@: goto crtmod_pop
endif
;画面モードの最大値の確認
if <cmp.w #$76FF,d1>,eq
move.l #$16000000+crtmod_modes-1,d0
; goto crtmod_pop
goto @b
endif
;設定前の画面モードを確認する
moveq.l #0,dPM
move.b BIOS_CRTMOD.w,dPM ;設定前の画面モード
swap.w dPM
;<dPM.l:設定前の画面モード<<16
;初期化するか
move.w d1,dPM
clr.b dPM
sub.w dPM,d1
;<d1.w:画面モード
;<dPM.w:$0000=初期化する,$0100=初期化しない,$4300=CRT向け,$4C00=LCD向け
;CRT向けとLCD向けのスイッチの切り替え
if <cmp.w #$4300,dPM>,eq ;CRT向け
move.b #$31,(SYSPORT_SRAM)E8 ;unlocksram
bclr.b #SRAM_XEIJ_LCD_BIT,(SRAM_XEIJ)ED
clr.b (SYSPORT_SRAM)E8 ;locksram
clr.w dPM ;初期化する
elif <cmp.w #$4C00,dPM>,eq ;LCD向け
move.b #$31,(SYSPORT_SRAM)E8 ;unlocksram
bset.b #SRAM_XEIJ_LCD_BIT,(SRAM_XEIJ)ED
clr.b (SYSPORT_SRAM)E8 ;locksram
clr.w dPM ;初期化する
endif
;<dPM.w:$0000=初期化する,$0100=初期化しない
;取得のみか
; IPLROM 1.0~1.3は$FFFFが取得のみ
; ここでは$xxFFを取得のみとする
; ただし$43FFと$4CFFはCRT向けとLCD向けのスイッチの切り替えだけ行う
goto <cmp.w #$00FF,d1>,eq,crtmod_end ;取得のみ
;設定後の画面モードが範囲外か
; IPLROM 1.0~1.3は$FFFFを除いて設定後の画面モードが範囲外のとき何も返さない
; ここでは$xxFFを除いて設定後の画面モードが範囲外のとき-1を返す
if <cmp.w #crtmod_modes,d1>,hs
moveq.l #-1,d0 ;設定後の画面モードが範囲外
goto crtmod_pop
endif
;設定する
;パラメータ1のアドレスを求める
lea.l crtmod_table_1_crt(pc),aP1
if <btst.b #SRAM_XEIJ_LCD_BIT,(SRAM_XEIJ)ED>,ne ;LCD向け
lea.l crtmod_table_1_lcd(pc),aP1
endif
move.w d1,d0
.if crtmod_param_1_size=8
lsl.w #3,d0
.else
mulu.w #crtmod_param_1_size,d0
.endif
adda.w d0,aP1
;<aP1.l:パラメータ1のアドレス
;パラメータ2のアドレスを求める
lea.l crtmod_table_2(pc),aP2
adda.w crtmod_param_1_2nd(aP1),aP2
;<aP2.l:パラメータ2のアドレス
;メモリモードを確認する
moveq.l #7,dMM
and.b crtmod_param_1_r20h(aP1),dMM ;メモリモード。0~7
;<dMM.w:メモリモード。0~7
;拡張グラフィック画面を確認する
; 拡張グラフィック画面がないのに拡張グラフィック画面が必要な画面モードが指定されたとき-2を返す
; 76543210
if <btst.b dMM,#%10100000>,ne ;メモリモード5,7。拡張グラフィック画面が必要
move.b (CRTC_MODE_BYTE)E8,-(sp) ;メモリモードを保存
move.b #7,(CRTC_MODE_BYTE)E8 ;メモリモードを7に変更
movea.l dGVRAM,a0
move.w (a0),d2 ;保存
not.w (a0) ;反転
move.w (a0),d0 ;d0=反転してから読み出したもの
move.w d2,(a0) ;復元
move.b (sp)+,(CRTC_MODE_BYTE)E8 ;メモリモードを復元
not.w d2 ;d2=読み出してから反転したもの
if <cmp.w d2,d0>,ne ;反転できていない
moveq.l #-2,d0 ;拡張グラフィック画面がない
goto crtmod_pop
endif
endif
;初期化するか
if <tst.w dPM>,eq
;初期化する
;設定後の画面モードを保存する
move.b d1,BIOS_CRTMOD.w ;設定後の画面モード
;グラフィック画面OFF、テキスト画面OFF、スプライト画面OFF
clr.w (VICON_VISIBLE)E8
;テキストカーソルOFF
IOCS _B_CUROFF
;テキストプレーン0~1をクリアする
; ラスタコピーを使うと速いがコードが長くなる
; 初回はCRTCが動いていないのでラスタコピーが終わらない
move.w #$0133,(CRTC_ACCESS)E8 ;同時アクセス開始
moveq.l #0,d0
lea.l $00E00000,a0 ;テキストVRAM
move.w #($00E20000-$00E00000)/(4*2)-1,d1 ;16384回
for d1
move.l d0,(a0)+
move.l d0,(a0)+
next
move.w #$0033,(CRTC_ACCESS)E8 ;同時アクセス終了
;グラフィック画面使用不可
clr.w BIOS_GRAPHIC_PALETS.w ;グラフィック画面の色数-1。0=グラフィック画面使用不可
;初期化する/しない共通
bsr crtmod_common
;CRTCコマンド停止
clr.w (CRTC_ACTION)E8
;グラフィックパレットを初期化する
.ifdef CRTMOD_REPRODUCE_BUG ;バグを再現させる
moveq.l #3,d0
and.b crtmod_param_2_r20l(aP2),d0 ;水平解像度。256x256=256色,512x512=512色,768x512=65536色
.else
move.w dMM,d0 ;メモリモード。0~7
.endif
PATCH_jsr g_clr_on,initialize_gpalet ;グラフィックパレットを初期化する
;グラフィックストレージON
; IPLROM 1.0~1.3の_CRTMODはグラフィックストレージONの状態で復帰する
bset.b #CRTC_GRAPHIC_STORAGE_BIT,(CRTC_MODE_BYTE)E8 ;グラフィックストレージON
;テキストカーソルON
IOCS _B_CURON
;テキストパレットを初期化する
lea.l (SRAM_TEXT_PALET_0)ED,a0
lea.l (VICON_TSPALET)E8,a1
move.l (a0)+,(a1)+ ;0,1
move.l (a0)+,(a1)+ ;2,3
move.l (a0),d0 ;d0=4|8
move.l d0,d1 ;d1=4|8
swap.w d0 ;d0=8|4
move.w d0,(a1)+ ;4
move.w d0,(a1)+ ;5
move.w d0,(a1)+ ;6
move.w d0,(a1)+ ;7
move.w d1,d0 ;d0=8|8
move.l d0,(a1)+ ;8,9
move.l d0,(a1)+ ;10,11
move.l d0,(a1)+ ;12,13
move.l d0,(a1)+ ;14,15
;コントラストを初期化する
move.b (SRAM_CONTRAST)ED,(SYSPORT_CONTRAST)E8
;スプライトコントローラを設定する
~i = SPRC_SPRITE_OFF|SPRC_BG_1_TEXT_1|SPRC_BG_1_OFF|SPRC_BG_0_TEXT_0|SPRC_BG_0_OFF
move.w #~i,(SPRC_CONTROL)EB
;テキスト画面ON
move.w #VICON_TXON_MASK,(VICON_VISIBLE)E8
;優先順位を設定する
~i = 0<<VICON_SPPR_BIT|1<<VICON_TXPR_BIT|2<<VICON_GRPR_BIT ;SP>TX>GR
~j = 3<<VICON_G4TH_BIT|2<<VICON_G3RD_BIT|1<<VICON_G2ND_BIT|0<<VICON_G1ST_BIT ;G1>G2>G3>G4
move.w #~i|~j,(VICON_PRIORITY)E8
else
;初期化しない
;設定後の画面モードを保存する
move.b d1,BIOS_CRTMOD.w ;設定後の画面モード
;グラフィック画面使用不可
clr.w BIOS_GRAPHIC_PALETS.w ;グラフィック画面の色数-1。0=グラフィック画面使用不可
;初期化する/しない共通
bsr crtmod_common
;グラフィック画面が表示されているか
moveq.l #VICON_GXON_MASK|VICON_G4ON_MASK|VICON_G3ON_MASK|VICON_G2ON_MASK|VICON_G1ON_MASK,d0
and.w (VICON_VISIBLE)E8,d0
if ne ;グラフィック画面が表示されているとき
;メモリモードを設定する
; ストレージは変化しない
moveq.l #.not.7,d0
and.b (CRTC_MODE_BYTE)E8,d0
or.b dMM,d0
move.b d0,(CRTC_MODE_BYTE)E8
move.w dMM,(VICON_MEMORY_MODE)E8
;BIOSワークエリアを初期化する
lea.l BIOS_GRAPHIC_PAGE.w,a0 ;BIOS_GRAPHIC_Y_OFFSET,BIOS_GRAPHIC_PALETS
move.l dGVRAM,(a0)+ ;描画ページ先頭アドレス
move.l #2*512,d0
if <cmp.w #4,dMM>,hs ;4~7
add.w d0,d0 ;2*1024
endif
move.l d0,(a0)+ ;Y方向オフセット
moveq.l #16-1,d0
; 76543210
if <btst.b dMM,#%00100010>,ne ;1,5
st.b d0 ;256-1
; 76543210
elif <btst.b dMM,#%10001100>,ne ;2,3,7
moveq.l #-1,d0 ;65536-1
endif
move.w d0,(a0) ;色数-1
endif
endif
;終了
;<dPM.l:設定前の画面モード<<16
crtmod_end:
clr.w dPM
swap.w dPM ;設定前の画面モード
move.l dPM,d0
crtmod_pop:
pop
rts
;初期化する/しない共通
crtmod_common:
;CRTCとシステムポートのR20,HRL,R00~R07を設定する
; すべての画面モードがメモリモード3になる
; ストレージはOFFになる
move.w #3<<8,d2 ;R20H(新)
move.b crtmod_param_2_r20l(aP2),d2 ;R20L(新)
;<d2.w:R20(新)
lea.l dot_clock_rank(pc),a0
moveq.l #%00011111,d0
and.b (CRTC_RESOLUTION_BYTE)E8,d0 ;R20L(古)
moveq.l #SYSPORT_HRL,d1
and.b (SYSPORT_MISC)E8,d1
neg.b d1
addx.b d0,d0 ;R20L<<1|HRL(古)
move.b (a0,d0.w),d0 ;古いドットクロックのランク
moveq.l #%00011111,d1
and.b d2,d1 ;R20L(新)
add.b d1,d1
add.b crtmod_param_2_hrl(aP2),d1 ;R20L<<1|HRL(新)
move.b (a0,d1.w),d1 ;新しいドットクロックのランク
if <cmp.b d0,d1>,lo ;ドットクロックが下がる
move.w d2,(CRTC_MODE_RESOLUTION)E8 ;R20
tst.b crtmod_param_2_hrl(aP2)
bsne.b #SYSPORT_HRL_BIT,(SYSPORT_MISC)E8 ;HRL
lea.l (CRTC_H_SYNC_END)E8,a0 ;R01
lea.l crtmod_param_2_r01(aP2),a1
move.w (a1)+,(a0)+ ;R01
move.l (a1)+,(a0)+ ;R02,R03
move.l (a1)+,(a0)+ ;R04,R05
move.l (a1)+,(a0)+ ;R06,R07
move.w crtmod_param_2_r00(aP2),(CRTC_H_FRONT_END)E8 ;R00
else ;ドットクロックが同じか上がる
lea.l (CRTC_H_FRONT_END)E8,a0 ;R00
lea.l crtmod_param_2_r00(aP2),a1
move.l (a1)+,(a0)+ ;R00,R01
move.l (a1)+,(a0)+ ;R02,R03
move.l (a1)+,(a0)+ ;R04,R05
move.l (a1)+,(a0)+ ;R06,R07
move.w d2,(CRTC_MODE_RESOLUTION)E8 ;R20
tst.b crtmod_param_2_hrl(aP2)
bsne.b #SYSPORT_HRL_BIT,(SYSPORT_MISC)E8 ;HRL
endif
;CRTCのR08を設定する
; 外部同期水平アジャスト
; スーパーインポーズするときビデオの映像とX68000の映像を重ねるために、
; ビデオとX68000の水平同期パルスの先頭の時間差を38.863632MHzのサイクル数で指定する
; 低解像度512x512のとき
; 水平同期パルス幅は4キャラクタ。R01=4-1=3
; 水平バックポーチは6キャラクタ。R02=4+6-5=5
; 外部同期水平アジャストは44
; perl -e "print((4.7+4.7)*38.863632-(4*8*(4+6))-1)"
; 44.3181408
; 低解像度256x256のとき。1ドット追加する
; 水平同期パルス幅は2キャラクタ。R01=2-1=1
; 水平バックポーチは3キャラクタ。R02=2+3-5=0
; 外部同期水平アジャストは36
; perl -e "print((4.7+4.7)*38.863632-(8*(8*(2+3)+1))-1)"
; 36.3181408
move.w crtmod_param_2_r08(aP2),(CRTC_ADJUST)E8 ;R08
;CRTCのR09~R19,R21~R24を初期化する
moveq.l #0,d0
lea.l (CRTC_RASTER)E8,a0 ;R09
move.w d0,(a0)+ ;R09
move.l d0,(a0)+ ;R10,R11
move.l d0,(a0)+ ;R12,R13
move.l d0,(a0)+ ;R14,R15
move.l d0,(a0)+ ;R16,R17
move.l d0,(a0)+ ;R18,R19
addq.l #2,a0
move.w #$0033,(a0)+ ;R21
move.l d0,(a0)+ ;R22,R23
move.w d0,(a0)+ ;R24
;ビデオコントローラのメモリモードを設定する
; すべての画面モードがメモリモード3になる
move.w #3,(VICON_MEMORY_MODE)E8
;スプライトコントローラを初期化する
;解像度
moveq.l #%1_11_11,d1
and.b crtmod_param_2_r20l(aP2),d1 ;R20L
;<d1.w:解像度
;水平バックポーチ終了カラム
moveq.l #4,d0
add.w crtmod_param_2_r02(aP2),d0
move.w d0,(SPRC_H_BACK_END)EB ;スプライト水平バックポーチ終了カラム。R02+4
;水平フロントポーチ終了カラム
; 水平バックポーチ終了カラムを設定後130us待ってから水平フロントポーチ終了カラムを設定する
; 水平フロントポーチ終了カラムは水平256ドットのときはR00と同じ値、それ以外は255
; Inside X68000に低解像度256x256のときだけR00と同じ値を、それ以外は255を設定すると書かれているが、
; 高解像度256x256のときも255にするとスプライトが崩れる場合がある
; 水平512ドットのときは255にしないと水平256ドットから水平512ドットに切り替えたときスプライトの水平方向の位置がずれることがある
; IPLROM 1.3はdbraでX68030 25MHzのとき500us待っている。060turboのときウエイトが不足する
moveq.l #500/50,d0 ;500us
bsr wait_50us ;50us単位のウェイト
moveq.l #%0_00_11,d0
and.b d1,d0
if eq ;水平256ドット
move.w crtmod_param_2_r00(aP2),(SPRC_H_FRONT_END)EB ;スプライト水平フロントポーチ終了カラム。R00
else ;水平256ドット以外
move.w #255,(SPRC_H_FRONT_END)EB ;スプライト水平フロントポーチ終了カラム。255
endif
;垂直バックポーチ終了ラスタ
move.w crtmod_param_2_r06(aP2),(SPRC_V_BACK_END)EB ;スプライト垂直バックポーチ終了ラスタ。R06
;解像度
move.b BIOS_CRTMOD.w,d0
if <cmp.b #36,d0>,hs ;36~
if <cmp.b #40,d0>,lo ;36/37/38/39 256x256(正方形)
moveq.l #%10000,d1 ;スプライトは256x256
elif <cmp.b #44,d0>,hs ;44~
ifor <cmp.b #48,d0>,lo,<cmp.b #60,d0>,eq,<cmp.b #73,d0>,eq ;44/45/46/47/60/73 512x256(※)
moveq.l #%10101,d1 ;スプライトは512x512
endif
endif
endif
move.w d1,(SPRC_RESOLUTION)EB ;スプライト解像度。--------|---|高解像度|垂直サイズ##|水平サイズ##
;グラフィック画面のクリッピングエリア
; 画面モード20~27は表示画面が実画面より大きいことに注意する
move.w crtmod_param_1_width(aP1),d0 ;幅
move.w crtmod_param_1_height(aP1),d1 ;高さ
if <cmp.w #4,dMM>,lo ;メモリモード0~3。512x512まで
move.w #512,d2
if <cmp.w d2,d0>,hi
move.w d2,d0
endif
if <cmp.w d2,d1>,hi
move.w d2,d1
endif
endif
subq.w #1,d0 ;X最大
subq.w #1,d1 ;Y最大
clr.l BIOS_GRAPHIC_LEFT.w ;BIOS_GRAPHIC_TOP
move.w d0,BIOS_GRAPHIC_RIGHT.w
move.w d1,BIOS_GRAPHIC_BOTTOM.w
;グラフィックVRAMのY方向のオフセット
;dMM= 0 1 2 3 4 5 6 7
moveq.l #4,d0 ; d0= 4 4 4 4 4 4 4 4
and.w dMM,d0 ; d0= 0 0 0 0 4 4 4 4
addq.w #4,d0 ; d0= 4 4 4 4 8 8 8 8
lsl.w #8,d0 ; d0=1024 1024 1024 1024 2048 2048 2048 2048
move.l d0,BIOS_GRAPHIC_Y_OFFSET.w
;グラフィック画面のページ数
;dMM=0 1 2 3 4 5 6 7
moveq.l #4,d0 ; d0=4 4 4 4 4 4 4 4
lsr.b dMM,d0 ; d0=4 2 1 0 0 0 0 0
seq.b d1 ; d1=0 0 0 -1 -1 -1 -1 -1
sub.b d1,d0 ; d0=4 2 1 1 1 1 1 1
move.b d0,BIOS_GRAPHIC_PAGES.w
;テキスト画面の位置
move.l #$00E00000,BIOS_TEXT_PLANE.w
clr.l BIOS_CONSOLE_OFFSET.w
;テキスト画面の大きさ
move.w crtmod_param_1_width(aP1),d0 ;幅
move.w crtmod_param_1_height(aP1),d1 ;高さ
lsr.w #3,d0 ;幅/8
lsr.w #4,d1 ;高さ/16。424は16で割り切れないことに注意
subq.w #1,d0 ;幅/8-1
subq.w #1,d1 ;高さ/16-1
move.w d0,BIOS_CONSOLE_RIGHT.w
move.w d1,BIOS_CONSOLE_BOTTOM.w
;テキストカーソルの位置
clr.l BIOS_CURSOR_COLUMN.w ;BIOS_CURSOR_ROW
;マウスカーソルの移動範囲
clr.l d1
move.l BIOS_GRAPHIC_RIGHT,d2 ;BIOS_GRAPHIC_BOTTOM
IOCS _MS_LIMIT ;IOCSコール$77 _MS_LIMIT マウスカーソルの移動範囲を設定する
rts
;パラメータ1(CRT向け)
crtmod_table_1_crt:
; WIDTH HEIGHT R20H 2ND 1ST
crtmod_param_1 512, 512, 4, 0 ; CRT 0
crtmod_param_1 512, 512, 4, 1 ; CRT 1
crtmod_param_1 256, 256, 4, 2 ; CRT 2
crtmod_param_1 256, 256, 4, 3 ; CRT 3
crtmod_param_1 512, 512, 0, 0 ; CRT 4
crtmod_param_1 512, 512, 0, 1 ; CRT 5
crtmod_param_1 256, 256, 0, 2 ; CRT 6
crtmod_param_1 256, 256, 0, 3 ; CRT 7
crtmod_param_1 512, 512, 1, 0 ; CRT 8
crtmod_param_1 512, 512, 1, 1 ; CRT 9
crtmod_param_1 256, 256, 1, 2 ; CRT 10
crtmod_param_1 256, 256, 1, 3 ; CRT 11
crtmod_param_1 512, 512, 3, 0 ; CRT 12
crtmod_param_1 512, 512, 3, 1 ; CRT 13
crtmod_param_1 256, 256, 3, 2 ; CRT 14
crtmod_param_1 256, 256, 3, 3 ; CRT 15
crtmod_param_1 768, 512, 4, 4 ; CRT 16
crtmod_param_1 1024, 424, 4, 5 ; CRT 17
crtmod_param_1 1024, 848, 4, 6 ; CRT 18
crtmod_param_1 640, 480, 4, 7 ; CRT 19
crtmod_param_1 768, 512, 1, 4 ; CRT 20
crtmod_param_1 1024, 424, 1, 5 ; CRT 21
crtmod_param_1 1024, 848, 1, 6 ; CRT 22
crtmod_param_1 640, 480, 1, 7 ; CRT 23
crtmod_param_1 768, 512, 3, 4 ; CRT 24
crtmod_param_1 1024, 424, 3, 5 ; CRT 25
crtmod_param_1 1024, 848, 3, 6 ; CRT 26
crtmod_param_1 640, 480, 3, 7 ; CRT 27
crtmod_param_1 384, 256, 4, 8 ; CRT 28
crtmod_param_1 384, 256, 0, 8 ; CRT 29
crtmod_param_1 384, 256, 1, 8 ; CRT 30
crtmod_param_1 384, 256, 3, 8 ; CRT 31
crtmod_param_1 512, 512, 4, 9 ; CRT 32
crtmod_param_1 512, 512, 0, 9 ; CRT 33
crtmod_param_1 512, 512, 1, 9 ; CRT 34
crtmod_param_1 512, 512, 3, 9 ; CRT 35
crtmod_param_1 256, 256, 4, 10 ; CRT 36
crtmod_param_1 256, 256, 0, 10 ; CRT 37
crtmod_param_1 256, 256, 1, 10 ; CRT 38
crtmod_param_1 256, 256, 3, 10 ; CRT 39
crtmod_param_1 512, 256, 4, 22 ; CRT 40
crtmod_param_1 512, 256, 0, 22 ; CRT 41
crtmod_param_1 512, 256, 1, 22 ; CRT 42
crtmod_param_1 512, 256, 3, 22 ; CRT 43
crtmod_param_1 512, 256, 4, 22 ; CRT 44
crtmod_param_1 512, 256, 0, 22 ; CRT 45
crtmod_param_1 512, 256, 1, 22 ; CRT 46
crtmod_param_1 512, 256, 3, 22 ; CRT 47
crtmod_param_1 512, 512, 5, 0 ; CRT 48
crtmod_param_1 512, 512, 5, 1 ; CRT 49
crtmod_param_1 256, 256, 5, 2 ; CRT 50
crtmod_param_1 256, 256, 5, 3 ; CRT 51
crtmod_param_1 768, 512, 5, 4 ; CRT 52
crtmod_param_1 1024, 424, 5, 5 ; CRT 53
crtmod_param_1 1024, 848, 5, 6 ; CRT 54
crtmod_param_1 640, 480, 5, 7 ; CRT 55
crtmod_param_1 384, 256, 5, 8 ; CRT 56
crtmod_param_1 512, 512, 5, 9 ; CRT 57
crtmod_param_1 256, 256, 5, 10 ; CRT 58
crtmod_param_1 512, 256, 5, 22 ; CRT 59
crtmod_param_1 512, 256, 5, 22 ; CRT 60
crtmod_param_1 512, 512, 7, 0 ; CRT 61
crtmod_param_1 512, 512, 7, 1 ; CRT 62
crtmod_param_1 256, 256, 7, 2 ; CRT 63
crtmod_param_1 256, 256, 7, 3 ; CRT 64
crtmod_param_1 768, 512, 7, 4 ; CRT 65
crtmod_param_1 1024, 424, 7, 5 ; CRT 66
crtmod_param_1 1024, 848, 7, 6 ; CRT 67
crtmod_param_1 640, 480, 7, 7 ; CRT 68
crtmod_param_1 384, 256, 7, 8 ; CRT 69
crtmod_param_1 512, 512, 7, 9 ; CRT 70
crtmod_param_1 256, 256, 7, 10 ; CRT 71
crtmod_param_1 512, 256, 7, 22 ; CRT 72
crtmod_param_1 512, 256, 7, 22 ; CRT 73
crtmod_table_1_crt_end:
;パラメータ1(LCD向け)
crtmod_table_1_lcd:
; WIDTH HEIGHT R20H 2ND 1ST
crtmod_param_1 512, 512, 4, 11 ; LCD 0
crtmod_param_1 512, 512, 4, 12 ; LCD 1
crtmod_param_1 256, 256, 4, 13 ; LCD 2
crtmod_param_1 256, 256, 4, 14 ; LCD 3
crtmod_param_1 512, 512, 0, 11 ; LCD 4
crtmod_param_1 512, 512, 0, 12 ; LCD 5
crtmod_param_1 256, 256, 0, 13 ; LCD 6
crtmod_param_1 256, 256, 0, 14 ; LCD 7
crtmod_param_1 512, 512, 1, 11 ; LCD 8
crtmod_param_1 512, 512, 1, 12 ; LCD 9
crtmod_param_1 256, 256, 1, 13 ; LCD 10
crtmod_param_1 256, 256, 1, 14 ; LCD 11
crtmod_param_1 512, 512, 3, 11 ; LCD 12
crtmod_param_1 512, 512, 3, 12 ; LCD 13
crtmod_param_1 256, 256, 3, 13 ; LCD 14
crtmod_param_1 256, 256, 3, 14 ; LCD 15
crtmod_param_1 768, 512, 4, 15 ; LCD 16
crtmod_param_1 768, 600, 4, 16 ; LCD 17
crtmod_param_1 768, 1024, 4, 17 ; LCD 18
crtmod_param_1 640, 480, 4, 18 ; LCD 19
crtmod_param_1 768, 512, 1, 15 ; LCD 20
crtmod_param_1 768, 600, 1, 16 ; LCD 21
crtmod_param_1 768, 1024, 1, 17 ; LCD 22
crtmod_param_1 640, 480, 1, 18 ; LCD 23
crtmod_param_1 768, 512, 3, 15 ; LCD 24
crtmod_param_1 768, 600, 3, 16 ; LCD 25
crtmod_param_1 768, 1024, 3, 17 ; LCD 26
crtmod_param_1 640, 480, 3, 18 ; LCD 27
crtmod_param_1 384, 256, 4, 19 ; LCD 28
crtmod_param_1 384, 256, 0, 19 ; LCD 29
crtmod_param_1 384, 256, 1, 19 ; LCD 30
crtmod_param_1 384, 256, 3, 19 ; LCD 31
crtmod_param_1 512, 512, 4, 20 ; LCD 32
crtmod_param_1 512, 512, 0, 20 ; LCD 33
crtmod_param_1 512, 512, 1, 20 ; LCD 34
crtmod_param_1 512, 512, 3, 20 ; LCD 35
crtmod_param_1 256, 256, 4, 21 ; LCD 36
crtmod_param_1 256, 256, 0, 21 ; LCD 37
crtmod_param_1 256, 256, 1, 21 ; LCD 38
crtmod_param_1 256, 256, 3, 21 ; LCD 39
crtmod_param_1 512, 256, 4, 23 ; LCD 40
crtmod_param_1 512, 256, 0, 23 ; LCD 41
crtmod_param_1 512, 256, 1, 23 ; LCD 42
crtmod_param_1 512, 256, 3, 23 ; LCD 43
crtmod_param_1 512, 256, 4, 23 ; LCD 44
crtmod_param_1 512, 256, 0, 23 ; LCD 45
crtmod_param_1 512, 256, 1, 23 ; LCD 46
crtmod_param_1 512, 256, 3, 23 ; LCD 47
crtmod_param_1 512, 512, 5, 11 ; LCD 48
crtmod_param_1 512, 512, 5, 12 ; LCD 49
crtmod_param_1 256, 256, 5, 13 ; LCD 50
crtmod_param_1 256, 256, 5, 14 ; LCD 51
crtmod_param_1 768, 512, 5, 15 ; LCD 52
crtmod_param_1 768, 600, 5, 16 ; LCD 53
crtmod_param_1 768, 1024, 5, 17 ; LCD 54
crtmod_param_1 640, 480, 5, 18 ; LCD 55
crtmod_param_1 384, 256, 5, 19 ; LCD 56
crtmod_param_1 512, 512, 5, 20 ; LCD 57
crtmod_param_1 256, 256, 5, 21 ; LCD 58
crtmod_param_1 512, 256, 5, 23 ; LCD 59
crtmod_param_1 512, 256, 5, 23 ; LCD 60
crtmod_param_1 512, 512, 7, 11 ; LCD 61
crtmod_param_1 512, 512, 7, 12 ; LCD 62
crtmod_param_1 256, 256, 7, 13 ; LCD 63
crtmod_param_1 256, 256, 7, 14 ; LCD 64
crtmod_param_1 768, 512, 7, 15 ; LCD 65
crtmod_param_1 768, 600, 7, 16 ; LCD 66
crtmod_param_1 768, 1024, 7, 17 ; LCD 67
crtmod_param_1 640, 480, 7, 18 ; LCD 68
crtmod_param_1 384, 256, 7, 19 ; LCD 69
crtmod_param_1 512, 512, 7, 20 ; LCD 70
crtmod_param_1 256, 256, 7, 21 ; LCD 71
crtmod_param_1 512, 256, 7, 23 ; LCD 72
crtmod_param_1 512, 256, 7, 23 ; LCD 73
;パラメータ2
crtmod_table_2:
; R20L HRL HT HS HB HD HF VT VS VB VD VF R08 2ND 1ST
crtmod_param_2 %10101, 0, 92, 10, 12, 64, 6, 568, 6, 35, 512, 15, 27 ; 0 CRT 0/4/8/12/48/61
crtmod_param_2 %00101, 0, 76, 4, 6, 64, 2, 260, 3, 14, 240, 3, 44 ; 1 CRT 1/5/9/13/49/62
crtmod_param_2 %10000, 0, 46, 5, 6, 32, 3, 568, 6, 35, 512, 15, 27 ; 2 CRT 2/6/10/14/50/63
crtmod_param_2 %00000, 0, 38, 2, 3, 32, 1, 260, 3, 14, 240, 3, 36 ; 3 CRT 3/7/11/15/51/64
crtmod_param_2 %10110, 0, 138, 15, 18, 96, 9, 568, 6, 35, 512, 15, 27 ; 4 CRT 16/20/24/52/65
crtmod_param_2 %10110, 0, 176, 16, 20, 128, 12, 465, 8, 25, 424, 8, 27 ; 5 CRT 17/21/25/53/66
crtmod_param_2 %11010, 0, 176, 16, 20, 128, 12, 465, 8, 25, 424, 8, 27 ; 6 CRT 18/22/26/54/67
crtmod_param_2 %10110, 0, 138, 15, 26, 80, 17, 568, 6, 51, 480, 31, 27 ; 7 CRT 19/23/27/55/68
crtmod_param_2 %10001, 1, 68, 7, 9, 48, 4, 568, 6, 35, 512, 15, 27 ; 8 CRT 28/29/30/31/56/69
crtmod_param_2 %10110, 0, 138, 15, 34, 64, 25, 568, 6, 35, 512, 15, 27 ; 9 CRT 32/33/34/35/57/70
crtmod_param_2 %10001, 1, 68, 7, 17, 32, 12, 568, 6, 35, 512, 15, 27 ; 10 CRT 36/37/38/39/58/71
crtmod_param_2 %10101, 0, 82, 6, 10, 64, 2, 625, 2, 66, 512, 45, 27 ; 11 LCD 0/4/8/12/48/61
crtmod_param_2 %10101, 0, 82, 6, 10, 64, 2, 625, 2, 82, 480, 61, 27 ; 12 LCD 1/5/9/13/49/62
crtmod_param_2 %10000, 0, 42, 3, 5, 32, 2, 625, 2, 66, 512, 45, 27 ; 13 LCD 2/6/10/14/50/63
crtmod_param_2 %10000, 0, 42, 3, 5, 32, 2, 625, 2, 82, 480, 61, 27 ; 14 LCD 3/7/11/15/51/64
crtmod_param_2 %10110, 0, 124, 9, 15, 96, 4, 625, 2, 66, 512, 45, 27 ; 15 LCD 16/20/24/52/65
crtmod_param_2 %10110, 0, 124, 9, 15, 96, 4, 625, 2, 22, 600, 1, 27 ; 16 LCD 17/21/25/53/66
crtmod_param_2 %11010, 0, 124, 9, 15, 96, 4, 625, 2, 66, 512, 45, 27 ; 17 LCD 18/22/26/54/67
crtmod_param_2 %10111, 0, 100, 12, 6, 80, 2, 525, 2, 33, 480, 10, 27 ; 18 LCD 19/23/27/55/68
crtmod_param_2 %10001, 1, 68, 7, 9, 48, 4, 625, 2, 66, 512, 45, 27 ; 19 LCD 28/29/30/31/56/69
crtmod_param_2 %10110, 0, 124, 9, 31, 64, 20, 625, 2, 66, 512, 45, 27 ; 20 LCD 32/33/34/35/57/70
crtmod_param_2 %10001, 1, 68, 7, 17, 32, 12, 625, 2, 66, 512, 45, 27 ; 21 LCD 36/37/38/39/58/71
crtmod_param_2 %10001, 0, 92, 10, 12, 64, 6, 568, 6, 35, 512, 15, 27 ; 22 CRT 40/41/42/43/44/45/46/47/59/60/72/73
crtmod_param_2 %10001, 0, 82, 6, 10, 64, 2, 625, 2, 66, 512, 45, 27 ; 23 LCD 40/41/42/43/44/45/46/47/59/60/72/73
;R20L<<1|HRL→ドットクロックのランク
; rank R20L HRL osc div dotclk mode
; 7 1**10 * 69.552 2 34.776 768x512(高)
; 6 1**11 * 50.350 2 25.175 640x480
; 5 1**01 0 69.552 3 23.184 512x512(高)
; 4 1**01 1 69.552 4 17.388 384x256
; 3 1**00 0 69.552 6 11.592 256x256(高)
; 2 0**01 * 38.864 4 9.716 512x512(低)
; 1 1**00 1 69.552 8 8.694
; 0 0**00 * 38.864 8 4.858 256x256(低)
; 0 0**1* * 38.864 8 4.858
dot_clock_rank:
.rept 4
.dc.b 0 ;0**00 0
.dc.b 0 ;0**00 1
.dc.b 2 ;0**01 0
.dc.b 2 ;0**01 1
.dc.b 0 ;0**10 0
.dc.b 0 ;0**10 1
.dc.b 0 ;0**11 0
.dc.b 0 ;0**11 1
.endm
.rept 4
.dc.b 3 ;1**00 0
.dc.b 1 ;1**00 1
.dc.b 5 ;1**01 0
.dc.b 4 ;1**01 1
.dc.b 7 ;1**10 0
.dc.b 7 ;1**10 1
.dc.b 6 ;1**11 0
.dc.b 6 ;1**11 1
.endm
;----------------------------------------------------------------
;IOCSコール$90 _G_CLR_ON グラフィック画面の消去とパレット初期化と表示ON
;>d0.l:0
;----------------------------------------------------------------
iocs_90_G_CLR_ON:
dMM reg d3 ;メモリモード
dGVRAM reg d5 ;$00C00000
aE8 reg a2 ;(~)E8のベースアドレス
aED reg a4 ;(~)EDのベースアドレス
aP1 reg a5 ;パラメータ1のアドレス
push d0-d2/dMM/dGVRAM/a0/aE8/aED/aP1
move.l #$00C00000,dGVRAM
;(~)E8でアクセスする
; $00E80000 CRTC
; $00E82000 VICON
; $00E84000 DMAC
; $00E86000 SUPERAREA
; $00E88000 MFP
; $00E8A000 RTC
; $00E8C000 PRNPORT
; $00E8E000 SYSPORT
lea.l $00E88000,aE8
E8 reg -$00E88000(aE8)
;(~)EDでアクセスする
; $00ED0000 SRAM
lea.l $00ED8000,aED
ED reg -$00ED8000(aED)
;現在の画面モードを確認する
moveq.l #0,d1
move.b BIOS_CRTMOD.w,d1 ;現在の画面モード
if <cmp.w #crtmod_modes,d1>,hs ;現在の画面モードが範囲外のとき
move.b (SRAM_CRTMOD)ED,d1 ;起動時の画面モードを使う
if <cmp.w #crtmod_modes,d1>,hs ;起動時の画面モードも範囲外のとき
moveq.l #16,d1 ;16を使う
.if 0
move.b #$31,(SYSPORT_SRAM)E8 ;unlocksram
move.b d1,(SRAM_CRTMOD)ED
clr.b (SYSPORT_SRAM)E8 ;locksram
.endif
endif
endif
;<d1.l:画面モード
;パラメータ1のアドレスを求める
lea.l crtmod_table_1_crt,aP1
if <btst.b #SRAM_XEIJ_LCD_BIT,(SRAM_XEIJ)ED>,ne ;LCD向け
lea.l crtmod_table_1_lcd,aP1
endif
move.w d1,d0
.if crtmod_param_1_size=8
lsl.w #3,d0
.else
mulu.w #crtmod_param_1_size,d0
.endif
adda.w d0,aP1
;<aP1.l:パラメータ1のアドレス
;メモリモードを確認する
moveq.l #7,dMM
and.b crtmod_param_1_r20h(aP1),dMM ;メモリモード。0~7
;<dMM.w:メモリモード。0~7
;テキスト画面のみON
move.w #VICON_TXON_MASK,(VICON_VISIBLE)E8
;メモリモードを設定する
move.b dMM,(CRTC_MODE_BYTE)E8
move.w dMM,(VICON_MEMORY_MODE)E8
;グラフィックVRAMをクリアする
bset.b #CRTC_GRAPHIC_STORAGE_BIT,(CRTC_MODE_BYTE)E8 ;グラフィックストレージON
movea.l dGVRAM,a0
moveq.l #0,d0
moveq.l #1-1,d2
; 76543210
if <btst.b dMM,#%10100000>,ne ;5,7
;メモリモードだけでクリアする範囲を決めている
;拡張グラフィック画面がないとき拡張グラフィック画面が必要な画面モードはCRTMODが弾くのでここを通ることはないはず
moveq.l #4-1,d2
endif
for d2
moveq.l #-1,d1 ;2*512*512/8=65536
for d1
move.l d0,(a0)+
move.l d0,(a0)+
next
next
bclr.b #CRTC_GRAPHIC_STORAGE_BIT,(CRTC_MODE_BYTE)E8 ;グラフィックストレージOFF
;BIOSワークエリアを初期化する
lea.l BIOS_GRAPHIC_PAGE.w,a0 ;BIOS_GRAPHIC_Y_OFFSET,BIOS_GRAPHIC_PALETS
move.l dGVRAM,(a0)+ ;描画ページ先頭アドレス
move.l #2*512,d0
if <cmp.w #4,dMM>,hs ;4~7
add.w d0,d0 ;2*1024
endif
move.l d0,(a0)+ ;Y方向オフセット
moveq.l #16-1,d0
; 76543210
if <btst.b dMM,#%00100010>,ne ;1,5
st.b d0 ;256-1
; 76543210
elif <btst.b dMM,#%10001100>,ne ;2,3,7
moveq.l #-1,d0 ;65536-1
endif
move.w d0,(a0) ;色数-1
;グラフィックパレットを初期化する
move.w dMM,d0
bsr initialize_gpalet
;テキスト画面ON、グラフィック画面ON
; if <cmp.w #4,dMM>,lo ;メモリモード0~3。512x512ドット
; move.w #VICON_TXON_MASK|VICON_G4ON_MASK|VICON_G3ON_MASK|VICON_G2ON_MASK|VICON_G1ON_MASK,(VICON_VISIBLE)E8
; else ;メモリモード4~7。1024x1024ドット
; move.w #VICON_TXON_MASK|VICON_GXON_MASK,(VICON_VISIBLE)E8
; endif
; IPLROM 1.0~1.3は1024x1024ドットと512x512ドットを両方ONにしている
move.w #VICON_TXON_MASK|VICON_GXON_MASK|VICON_G4ON_MASK|VICON_G3ON_MASK|VICON_G2ON_MASK|VICON_G1ON_MASK,(VICON_VISIBLE)E8
moveq.l #0,d0
pop
rts
;----------------------------------------------------------------
;グラフィックパレットを初期化する
;<d0.w:メモリモード。0~7
initialize_gpalet:
push d0-d4/a0-a1
lea.l VICON_GPALET,a0
ifor <tst.w d0>,eq,<cmp.w #4,d0>,eq,<cmp.w #6,d0>,eq ;メモリモード0,4,6。16色
lea.l gpalet_16_array(pc),a1
moveq.l #16/2-1,d0
for d0
move.l (a1)+,(a0)+
next
elifor <cmp.w #1,d0>,eq,<cmp.w #5,d0>,eq ;メモリモード1,5。256色
;greenは増分10.5で4階調(10.5*3=31.5)、redとblueは増分4.5で8階調(4.5*7=31.5)、端数は切り捨て
move.l #((9<<1)<<16)|(9<<1),d1 ;blueの増分4.5+4.5
moveq.l #0,d3 ;green=0
do
moveq.l #(4<<1),d2 ;red=0,blue=(0,4.5)
moveq.l #8-1,d4
for d4
move.l d3,d0 ;green
and.l #.not.(((1<<10)<<16)|(1<<10)),d0 ;greenの端数を切り捨てる
add.l d2,d0 ;red,blue=(0,4.5)
and.l #.not.(((1<<5)<<16)|(1<<5)),d0 ;redの端数を切り捨てる
move.l d0,(a0)+
add.l d1,d0 ;blue+=4.5+4.5
move.l d0,(a0)+
add.l d1,d0 ;blue+=4.5+4.5
move.l d0,(a0)+
add.l d1,d0 ;blue+=4.5+4.5
move.l d0,(a0)+
add.l #((9<<5)<<16)|(9<<5),d2 ;red+=4.5
next
add.l #((21<<10)<<16)|(21<<10),d3 ;green+=10.5
while cc
else ;メモリモード2,3,7。65536色
move.l #$00_01_00_01,d0 ;(L00,L01,H00,H01),(L02,L03,H02,H03),…,(LFE,LFF,HFE,HFF)
move.l #$02_02_02_02,d2
moveq.l #256/2-1,d1
for d1
move.l d0,(a0)+
add.l d2,d0
next
endif
pop
rts
;グラフィック16色パレット
gpalet_16_array:
dcrgb 0,0,0
dcrgb 10,10,10
dcrgb 0,0,16
dcrgb 0,0,31
dcrgb 16,0,0
dcrgb 31,0,0
dcrgb 16,0,16
dcrgb 31,0,31
dcrgb 0,16,0
dcrgb 0,31,0
dcrgb 0,16,16
dcrgb 0,31,31
dcrgb 16,16,0
dcrgb 31,31,0
dcrgb 21,21,21
dcrgb 31,31,31
;----------------------------------------------------------------
;50us単位のウェイト
;<d0.l:時間(50us単位)
.text
.even
wait_50us:
.if 0
;Timer-Cを使う
; Timer-Cが1/200プリスケール(50us)で動作していなければならない
aTCDR reg a0
push d0-d2/aTCDR
lea.l MFP_TCDR,aTCDR
moveq.l #0,d1
move.b (aTCDR),d1
move.b (aTCDR),d1
do
moveq.l #0,d2
move.b (aTCDR),d2
redo <cmp.b (aTCDR),d2>,cs
sub.w d2,d1
if cs
add.w #200,d1
endif
exg.l d1,d2
sub.l d2,d0
while hi
pop
rts
.else
;dbra空ループを使う
; BIOS_MPU_SPEED_ROM.wとBIOS_MPU_TYPE.wが設定されていなければならない
push d0-d3
subq.l #1,d0
if cc
move.l BIOS_MPU_SPEED_ROM_LONG.w,d1
if eq
move.w BIOS_MPU_SPEED_ROM.w,d1
endif
; 上限を20bitとして50usあたりのdbraの回数を求める
if <cmpi.b #4,BIOS_MPU_TYPE.w>,lo ;000/010/020/030
move.w #205,d2 ;2**12*50/1000=204.8
elif eq ;040
move.w #307,d2 ;2**12*50/1000*6/4=307.2
else ;060
move.w #1229,d2 ;2**12*50/1000*6/1=1228.8
endif
move.l d1,d3 ;d3=H|L
swap.w d3 ;d3=L|H
mulu.w d2,d3 ;d3=c*H
mulu.w d2,d1 ;d1=c*L
swap.w d3
clr.w d3 ;d3=c*H|0
add.l d3,d1 ;d1=c*(H|L)
and.w #$F000,d1 ;43210___
rol.l #4,d1 ;3210___4
swap.w d1 ;___43210 50usあたりのdbraの回数
subq.l #1,d1
move.l d1,d2
forlong d0
move.l d2,d1
.align 16,$2048
forlong d1
next
next
endif
pop
rts
.endif
;----------------------------------------------------------------
;デバイスドライバの末尾
device_tail:
;----------------------------------------------------------------
;デバイスコマンド0 初期化
initialize:
;パラメータを確認する
moveq.l #-1,d6 ;CRT/LCDは指定されていない
moveq.l #-1,d7 ;画面モードは指定されていない
movea.l 18(a5),a0 ;パラメータ。区切りは0、末尾は0,0。先頭はデバイスファイル名
do
while <tst.b (a0)+>,ne ;デバイスファイル名を読み飛ばす
dostart
gotoand <cmp.b #'-',d0>,ne,<cmp.b #'/',d0>,ne,parameter_error ;-,/以外
move.b (a0)+,d0
goto eq,parameter_error ;-,/の後に文字がない
bsr tolower
if <cmp.b #'l',d0>,eq ;-l
goto <tst.l d6>,pl,parameter_error ;CRT/LCDは既に指定されている
ifand <tst.b (a0)>,eq,<tst.b 1(a0)>,ne ;10進数が離れている
addq.l #1,a0
endif
bsr nonspace
bsr stou
gotoor <>,cs,<cmp.l #1,d0>,hi,parameter_error ;10進数がないか範囲外
move.l d0,d6 ;CRT/LCDが指定された
elif <cmp.b #'m',d0>,eq ;-m
goto <tst.l d7>,pl,parameter_error ;画面モードは既に指定されている
ifand <tst.b (a0)>,eq,<tst.b 1(a0)>,ne ;10進数が離れている
addq.l #1,a0
endif
bsr nonspace
bsr stou
gotoor <>,cs,<cmp.l #47,d0>,hi,parameter_error ;10進数がないか範囲外
move.l d0,d7 ;画面モードが指定された
else ;-l,-m以外
goto parameter_error
noreturn
endif
goto <tst.b (a0)+>,ne,parameter_error ;余分な文字がある
start
move.b (a0)+,d0
while ne
;<d6.l:0=CRT,1=LCD,-1=指定されていない
;<d7.l:画面モード,-1=指定されていない
;ベクタを変更する
lea.l vector_table(pc),a0 ;ベクタテーブル
bsr set_vector ;ベクタを変更する
;画面モードを設定する
bsr set_screen_mode
;タイトルを表示する
pea.l crlf_title(pc)
DOS _PRINT
peastrdata <'CRTMOD/G_CLR_ONを拡張します',13,10>
DOS _PRINT
addq.l #8,sp
;デバイスドライバの末尾を設定する
move.l #device_tail,14(a5) ;デバイスドライバの末尾
;デバイスドライバを組み込む
moveq.l #0,d0
rts
;パラメータエラー
parameter_error:
;タイトルとエラーメッセージを表示する
pea.l crlf_title(pc)
DOS _PRINT
peastrdata <'指定できないパラメータです',13,10>
DOS _PRINT
addq.l #8,sp
;デバイスドライバを組み込まない
move.w #ABORT|MISCELLANEOUS_ERROR,d0 ;中止(A) エラーが発生しました
rts
;----------------------------------------------------------------
;実行開始
execution_start:
;オプションを確認する
moveq.l #-1,d5 ;常駐/解除は指定されていない
moveq.l #-1,d6 ;CRT/LCDは指定されていない
moveq.l #-1,d7 ;画面モードは指定されていない
lea.l 1(a2),a0
dostart
gotoand <cmp.b #'-',d0>,ne,<cmp.b #'/',d0>,ne,usage_exit ;-,/以外
addq.l #1,a0
move.b (a0)+,d0
goto eq,usage_exit ;-,/の後に文字がない
bsr tolower
if <cmp.b #'e',d0>,eq ;-e
goto <tst.l d5>,pl,usage_exit ;常駐/解除は既に指定されている
moveq.l #0,d5 ;常駐
elif <cmp.b #'l',d0>,eq ;-l
goto <tst.l d6>,pl,usage_exit ;CRT/LCDは既に指定されている
bsr nonspace
bsr stou
gotoor <>,cs,<cmp.l #1,d0>,hi,usage_exit ;10進数がないか範囲外
move.l d0,d6 ;CRT/LCDが指定された
elif <cmp.b #'m',d0>,eq ;-m
goto <tst.l d7>,pl,usage_exit ;画面モードは既に指定されている
bsr nonspace
bsr stou
gotoor <>,cs,<cmp.l #47,d0>,hi,usage_exit ;10進数がないか範囲外
move.l d0,d7 ;画面モードが指定された
elif <cmp.b #'r',d0>,eq ;-r
goto <tst.l d5>,pl,usage_exit ;常駐/解除は既に指定されている
moveq.l #1,d5 ;解除
else ;-e,-l,-m,-r以外
goto usage_exit
noreturn
endif
start
bsr nonspace
while ne
;<d5.l:0=常駐,1=解除,-1=指定されていない
;<d6.l:0=CRT,1=LCD,-1=指定されていない
;<d7.l:画面モード,-1=指定されていない
;常駐/解除が指定されていないときは画面モードだけ設定する
if <tst.l d5>,mi ;常駐/解除が指定されていない
gotoand <tst.l d6>,mi,<tst.l d7>,mi,usage_exit ;CRT/LCDと画面モードも指定されていない
bsr set_screen_mode ;画面モードを設定する
goto exit ;終了する
noreturn
endif
;スーパーバイザモードへ移行する
supervisormode
;常駐部分を探す
;デバイスドライバを探す
movea.l DOS_HUMAN_MEMORY.w,a2 ;Human68kの先頭
do
addq.l #2,a2
whileor <cmpi.l #'NUL ',DH_NAME(a2)>,ne,<cmpi.l #' ',DH_NAME+4(a2)>,ne,<cmpi.w #$8024,DH_TYPE(a2)>,ne ;NULデバイスまで進む。必ずある
while <movea.l a2,a3>,<movea.l DH_NEXT(a2),a2>,<cmpa.l #-1,a2>,ne ;次のデバイスドライバ
lea.l DH_NAME(a2),a0 ;常駐部分のデバイス名
lea.l program_head+DH_NAME(pc),a1 ;自分のデバイス名
gotoand <cmpm.l (a0)+,(a1)+>,eq,<cmpm.l (a0)+,(a1)+>,eq,end_of_search ;一致したら終了
endwhile
suba.l a3,a3 ;常駐部分はデバイスドライバではない
;手前にある常駐プログラムを探す
lea.l program_head(pc),a2 ;常駐部分の先頭
while <movea.l MM_PREV-MM_PROGRAM(a2),a2>,<move.l a2,d0>,ne ;直前のメモリ管理テーブル
lea.l MM_PROGRAM(a2),a2 ;常駐部分の先頭
lea.l DH_SIZE(a2),a0 ;常駐部分のデバイスヘッダの末尾
continue <cmpa.l MM_TAIL-MM_PROGRAM(a2),a0>,hi ;メモリブロックが短すぎる
lea.l DH_NAME(a2),a0 ;常駐部分のデバイス名
lea.l program_head+DH_NAME(pc),a1 ;自分のデバイス名
gotoand <cmpm.l (a0)+,(a1)+>,eq,<cmpm.l (a0)+,(a1)+>,eq,end_of_search ;一致したら終了
endwhile
;後ろにある常駐プログラムを探す
lea.l program_head(pc),a2 ;常駐部分の先頭
while <movea.l MM_NEXT-MM_PROGRAM(a2),a2>,<move.l a2,d0>,ne ;直後のメモリ管理テーブル
lea.l MM_PROGRAM(a2),a2 ;常駐部分の先頭
lea.l DH_SIZE(a2),a0 ;常駐部分のデバイスヘッダの末尾
continue <cmpa.l MM_TAIL-MM_PROGRAM(a2),a0>,hi ;メモリブロックが短すぎる
lea.l DH_NAME(a2),a0 ;常駐部分のデバイス名
lea.l program_head+DH_NAME(pc),a1 ;自分のデバイス名
gotoand <cmpm.l (a0)+,(a1)+>,eq,<cmpm.l (a0)+,(a1)+>,eq,end_of_search ;一致したら終了
endwhile
end_of_search:
;<a2.l:常駐部分の先頭,0=常駐部分が見つからない
;<a3.l:(常駐部分が見つかったとき)常駐部分の前のデバイスドライバ。0=常駐部分はデバイスドライバではない
if <move.l a2,d0>,eq ;常駐していない
if <tst.l d5>,ne ;解除
;ユーザモードへ復帰する
usermode
;エラーメッセージを表示する
move.w #2,-(sp)
peastrdata <'常駐していません',13,10>
DOS _FPUTS
addq.l #6,sp
;エラー終了する
move.w #1,-(sp)
DOS _EXIT2
noreturn
endif
;常駐
;ベクタを変更する
lea.l vector_table(pc),a0 ;ベクタテーブル
bsr set_vector ;ベクタを変更する
;ユーザモードへ復帰する
usermode
;画面モードを設定する
bsr set_screen_mode
;常駐メッセージを表示する
pea.l title(pc)
DOS _PRINT
peastrdata <'常駐しました',13,10>
DOS _PRINT
addq.l #8,sp
;常駐終了する
clr.w -(sp)
move.l #device_tail-program_head,-(sp)
DOS _KEEPPR
noreturn
else ;常駐している
if <tst.l d5>,eq ;常駐
;ユーザモードに復帰する
usermode
;エラーメッセージを表示する
move.w #2,-(sp)
peastrdata <'常駐しています',13,10>
DOS _FPUTS
addq.l #6,sp
;エラー終了する
move.w #1,-(sp)
DOS _EXIT2
noreturn
endif
;解除
;ベクタを確認する
lea.l (vector_table-program_head)(a2),a0 ;常駐部分のベクタテーブル
bsr check_vector ;ベクタを確認する
if ne ;ベクタが変更されている
;ユーザモードに復帰する
usermode
;エラーメッセージを表示する
move.w #2,-(sp)
peastrdata <'ベクタが変更されています。解除できません',13,10>
DOS _FPUTS
addq.l #6,sp
;エラー終了する
move.w #1,-(sp)
DOS _EXIT2
noreturn
endif
;ベクタが変更されていない
;ベクタを復元する
lea.l (vector_table-program_head)(a2),a0 ;常駐部分のベクタテーブル
bsr release_vector ;ベクタを復元する
if <move.l a3,d0>,ne ;常駐部分はデバイスドライバ
;デバイスドライバを切り離す
move.l (a2),(a3) ;前のデバイスドライバに次のデバイスドライバを繋ぐ
else ;常駐部分は常駐プログラム
;常駐部分を開放する
pea.l MM_SIZE-MM_PROGRAM(a2) ;常駐部分のメモリブロックの先頭
DOS _MFREE
addq.l #4,sp
endif
;ユーザモードに復帰する
usermode
;メッセージを表示する
peastrdata <'解除しました',13,10>
DOS _PRINT
addq.l #4,sp
;終了する
DOS _EXIT
noreturn
endif
;タイトルと使用法を表示する
usage_exit:
pea.l title(pc)
DOS _PRINT
pea.l usage(pc)
DOS _PRINT
addq.l #8,sp
;終了する
exit:
DOS _EXIT
;----------------------------------------------------------------
;ベクタを変更する
;<a0.l:ベクタテーブル
set_vector:
push d0/a0-a1
docontinue
movea.w d0,a1 ;オフセット
move.l (a1),d0
move.l (a0)+,(a1) ;新しいベクタ
move.l d0,(a0)+ ;古いベクタ
while <move.w (a0)+,d0>,ne
pop
rts
;----------------------------------------------------------------
;ベクタを確認する
;<a0.l:常駐部分のベクタテーブル
;>ccr:eq=ベクタは変更されていない,ne=ベクタが変更されている
check_vector:
push d0/a0-a1
docontinue
movea.w d0,a1 ;オフセット
move.l (a1),d0
break <cmp.l (a0)+,d0>,ne ;新しいベクタが現在のベクタと一致しなければ失敗
addq.l #4,a0 ;古いベクタを読み飛ばす
while <move.w (a0)+,d0>,ne
pop
rts
;----------------------------------------------------------------
;ベクタを復元する
;<a0.l:常駐部分のベクタテーブル
release_vector:
push d0/a0-a1
docontinue
movea.w d0,a1 ;オフセット
addq.l #4,a0 ;新しいベクタを読み飛ばす
move.l (a0)+,(a1) ;古いベクタ
while <move.w (a0)+,d0>,ne
pop
rts
;----------------------------------------------------------------
;画面モードを設定する
;<d6.l:0=CRT,1=LCD,-1=指定されていない
;<d7.l:画面モード,-1=指定されていない
set_screen_mode:
if <tst.l d7>,pl ;画面モードが指定されている
move.l #(14<<16)|3,-(sp) ;ファンクションを表示しない
DOS _CONCTRL
addq.l #4,sp
move.l d7,d1 ;画面モード
if <tst.l d6>,pl ;LCDモードが指定されている
if eq ;CRT向け
or.w #$4300,d1
else ;LCD向け
or.w #$4C00,d1
endif
endif
IOCS _CRTMOD
; IOCS _G_CLR_ON
elif <tst.l d6>,pl ;LCDモードが指定されている
if eq ;CRT向け
move.w #$43FF,d1
else ;LCD向け
move.w #$4CFF,d1
endif
IOCS _CRTMOD
move.l #(16<<16)|$FFFF,-(sp) ;DOSレベルの画面モードを再設定する
DOS _CONCTRL
move.w d0,2(sp)
DOS _CONCTRL
addq.l #4,sp
move.l #(14<<16)|0,-(sp) ;ファンクションを表示する
DOS _CONCTRL
addq.l #4,sp
endif
rts
;----------------------------------------------------------------
;空白以外の文字まで読み飛ばす
;<a0.l:文字列
;>d0.l:空白以外の文字または0
;>a0.l:空白以外の文字または0の位置
;>z:eq=0
nonspace:
moveq.l #0,d0
do
move.b (a0)+,d0 ;次の文字
redoand <cmp.b #9,d0>,hs,<cmp.b #13,d0>,ls ;\t\n\v\f\rならば繰り返す
while <cmp.b #' ',d0>,eq ;空白ならば繰り返す
subq.l #1,a0 ;進み過ぎた分戻る
tst.l d0
rts
;----------------------------------------------------------------
;10進数の文字列を符号なし整数に変換する
;<a0.l:10進数の文字列。先頭の空白は認めない
;>d0.l:(ccのとき)符号なし整数。(csのとき)0=10進数の文字がない,-1=オーバーフロー
;>a0.l:(ccのとき)10進数の文字列の次の位置。(csのとき)変化しない
;>z:(ccのとき)eq=符号なし整数が0
;>v:(csのとき)vc=10進数の文字がない,vs=オーバーフロー
;>c:cs=10進数の文字がないまたはオーバーフロー
stou::
push d1-d2/a1
moveq.l #0,d0 ;符号なし整数
moveq.l #0,d1 ;文字
movea.l a0,a1 ;開始位置
dostart
goto <cmp.l #$1999999A,d0>,hs,20f ;10倍したらオーバーフローする
move.l d0,d2 ;1倍
lsl.l #2,d0 ;4倍
add.l d2,d0 ;5倍
add.l d0,d0 ;10倍して
add.l d1,d0 ;1桁加える
goto cs,20f ;オーバーフローした
start
move.b (a0)+,d1 ;次の文字
sub.b #'0',d1 ;整数にする
whileand <>,hs,<cmp.b #10,d1>,lo ;10進数の文字ならば繰り返す
subq.l #1,a0 ;進み過ぎた分戻る
goto <cmpa.l a1,a0>,eq,30f ;進んでいない。10進数の文字がない
tst.l d0 ;ne/eq,vc,cc
10: pop
rts
;オーバーフロー
20:
.if 0
do
move.b (a0)+,d1 ;次の文字
sub.b #'0',d1 ;整数にする
whileand <>,hs,<cmp.b #10,d1>,lo ;10進数の文字を読み飛ばす
subq.l #1,a0 ;進み過ぎた分戻る
.else
movea.l a1,a0 ;開始位置に戻る
.endif
moveq.l #-1,d0 ;オーバーフロー
move.w #%00011,ccr ;ne,vs,cs
goto 10b
;10進数の文字がない
30:
; moveq.l #0,d0 ;10進数の文字がない
move.w #%00101,ccr ;eq,vc,cs
goto 10b
;----------------------------------------------------------------
;小文字にする
;<d0.b:文字
;>d0.b:文字
tolower:
ifand <cmp.b #'A',d0>,hs,<cmp.b #'Z',d0>,ls ;大文字
add.b #'a'-'A',d0 ;小文字にする
endif
rts
.data
;----------------------------------------------------------------
;タイトル
crlf_title:
.dc.b 13,10
title:
.dc.b TITLE_STRING,13,10,0
.even
;使用法
usage:
.dc.b 13,10
.dc.b '説明',13,10
.dc.b ' crtmod16.xはIPLROM 1.6に含まれるCRTMOD/G_CLR_ONを常駐プログラムにしたものです。',13,10
.dc.b ' 一般的な液晶モニタで768x512ドットの画面をはみ出さないように表示できます。',13,10
.dc.b ' 384x256ドット、512x512ドット(正方形)などの画面モードが追加されます。',13,10
.dc.b 13,10
.dc.b '補足',13,10
.dc.b ' IPLROM 1.0~1.3にあったグラフィックパレットに関するバグが修正されます。',13,10
.dc.b ' バグに依存しているソフトウェアが誤動作する場合はcrtmrb16.xを組み込んでください。',13,10
.dc.b 13,10
.dc.b 'オプション',13,10
.dc.b ' -e 常駐します。',13,10
.dc.b ' -l 0~1 0でCRT向けの同期周波数、1でLCD向けの同期周波数を選択します。',13,10
.dc.b ' -m 0~73 画面モードを選択します。crtmodtest.xの説明を参照してください。',13,10
.dc.b ' -r 常駐を解除します。',13,10
.dc.b 13,10
.dc.b 0
.even
.end execution_start