BIOS09内CONOUTの画面制御を強化してみました。
実装したのは中部本多通商のS1-CP/M80で使用されていたコード+シフトJIS漢字表示です。
漢字表示はS1のシステムシステムコールではJIS漢字コードなのでCONOUT内で
シフトJISからJIS漢字に変換しています。
上記の例は、
$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$FF $1F,$41,$42,$43,$1B,$28,$44,$45,$46,$1B,$29,$47,$48,$49,$0D,$1F,$FF $1E,$1C,$1C,$1C,$1C,$1C,$1C,$1C,$05,$0D,$FF $41,$1C,$1F,$42,$1C,$1F,$43,$1C,$44,$45,$08,$46,$1E,$1C,$47,$1C,$1E,$48,$07,$FF $1B,$3D,$10,$12,$49,$1B,$28,$4A,$1B,$29,$4B,$FF $1F,$0D,$FF $31,$32,$33,$34,$35,$36,$37,$38,$39,$30,$31,$32,$33,$34,$35,$36 $37,$38,$39,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$30,$31,$32 $33,$34,$35,$36,$37,$38,$39,$30,$FF
を表示したもので、DEFで色反転、1行中の任意位置以降削除で15行目の8文字目以降を削除、カーソル操作で上下左右とEをバックスペース、LOCATE操作(Jを反転)とベル出力です。
実装したコードはこんな感じで、
2バイトエスケープシーケンス系 6種類。
ESC ( (1B28) 以後の文字表示で文字色と背景色が入れ替る→反転表示
ESC ) (1B29) 以後の文字表示で文字色と背景色が戻る→反転解除
ESC * (1B2A) スクリーンをクリアしてカーソルを左上に移動
ESC = (1B3D) カーソルを指定位置に移動→1B,3D,Y座標,X座標
ESC T (1B54) カーソル位置以降1行消去
ESC Y (1B59) カーソル位置以降1画面消去
1バイトコントロールコード系 17種類
$05 カーソル以降1行消去
$06 カーソルをスクリーンの右下に移動
$07 ベルを鳴らす
$08 カーソルを左に移動(BS)
$09 カーソルを次のタブストップ位置に移動
$0A カーソルを一つ下に移動(LF)
$0B カーソルをスクリーン左上に移動(ホーム)
$0C スクリーンをクリアしてカーソルをスクリーン左上に移動
$0D カーソルを次の行の先頭に移動(改行復帰)
$13 カーソルの位置にスペースを挿入
残 $14 カーソルの位置にタブストップを設定
$16 カーソルを表示する
$17 カーソルを表示しない
残 $19 カーソル位置のタブストップを解除する
$1B エスケープシーケンスの開始
$1C カーソルを一文字右へ移動
$1D カーソルを一文字左へ移動
$1E カーソルを一文字上へ移動
$1F カーソルを一文字下へ移動
かなりベタな書き方だと思いますが、とりあえず動作しているようなので晒しておきます^^;;;
お気付きの点がありましたら、アドバイスお願い致します (_ _)
# S1-CP/M80用BIOS09 コンソール制御実験 その1
# 目標
# CONOUTの拡張
# 1)制御文字 2)エスケープシーケンス
# →:1C , ←:1D, ↑:1E, ↓:1F, ベル:07, BS:08, タブ:09, LF:0A, ホーム:0B, FF:0C
# OUTSCRで対応されているもの⇒0A,0C,07,08,09,0B
# 2)エスケープシーケンス ESC(1B)+SP+CODE
# 画面クリア:*, 反転文字:( ,反転解除:),行末までクリア:T,カーソル以降クリア:Y
# 3)SJIS漢字表示(2バイト)
# 残件
# ESC >の実装,漢字スクロール
org $D000
jmp START
#+++ 変数領域
CHRBUF_K1 fcb $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A
fcb $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A
fcb $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A
fcb $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A
fcb $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A
fcb $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A
fcb $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A
fcb $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A
fcb $8A,$BF,$8E,$9A,$8A,$BF,$8E,$9A,$FF
CHRBUF_C1: fcb $1F,$41,$42,$43,$1B,$28,$44,$45,$46,$1B,$29,$47,$48,$49,$0D,$1F,$FF
CHRBUF_C2: fcb $1E,$1C,$1C,$1C,$1C,$1C,$1C,$1C,$05,$0D,$FF
CHRBUF_C3: fcb $41,$1C,$1F,$42,$1C,$1F,$43,$1C,$44,$45,$08,$46,$1E,$1C,$47,$1C,$1E,$48,$07,$FF
CHRBUF_C4: fcb $1B,$3D,$10,$12,$49,$1B,$28,$4A,$1B,$29,$4B,$FF
CHRBUF_C5: fcb $1F,$0D,$FF
CHRBUF1: fcb $31,$32,$33,$34,$35,$36,$37,$38,$39,$30,$31,$32,$33,$34,$35,$36
fcb $37,$38,$39,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$30,$31,$32
fcb $33,$34,$35,$36,$37,$38,$39,$30,$FF
#+++ プログラム本体
START: clr ESC_ProcFlag
clr ArgvCount
leax CHRBUF_K1,PCR
lbsr CONOUT
leax CHRBUF_C1,PCR
lbsr CONOUT
leax CHRBUF1,PCR
lbsr CONOUT
leax CHRBUF1,PCR
lbsr CONOUT
leax CHRBUF1,PCR
lbsr CONOUT
leax CHRBUF1,PCR
lbsr CONOUT
leax CHRBUF1,PCR
lbsr CONOUT
leax CHRBUF_C2,PCR
lbsr CONOUT
leax CHRBUF_C3,PCR
lbsr CONOUT
leax CHRBUF_C4,PCR
lbsr CONOUT
leax CHRBUF_C5,PCR
lbsr CONOUT
jmp S1MON
#+++ CONOUTサブルーチン
CONOUT: pshs A,B,X
CONOUT1: lda ,X+
cmpa #$FF
lbeq CONOUT_END ;終端検出←CP/M内では削除
ldb ESC_ProcFlag
lbne CONOUT_ESC ;ESCシーケンス処理中
ldb SJIS_ProcFlag
lbne CONOUT_SJIS ;SJIS処理中
cmpa #$81
lbcc CONOUT_SJIS ;SJISコード処理
cmpa #$1B
lbne CONOUT2 ;ESCシーケンス以外
ldb #$FF
stb ESC_ProcFlag ;ESCシーケンス処理中セット
lbra CONOUT1
CONOUT2: cmpa #$0D ;
beq CONOUT3
cmpa #$05
beq CONOUT4
cmpa #$06
beq CONOUT5
cmpa #$16
beq CONOUT6
cmpa #$17
beq CONOUT7
cmpa #$13
beq CONOUT8
lbsr OUTSCR ;文字or制御文字のESCシーケンス以外出力
bra CONOUT1
CONOUT3: pshs D,X,Y ;復帰改行
swi2
fcb $41,75 ;CURSRD
clra ;X=0
swi2
fcb $41,8 ;CURSET
lda #$0A
lbsr OUTSCR
puls D,X,Y
lbra CONOUT1
CONOUT4: lbra CONOUT_ESC4 ;カーソル以降1行消去(CONOUT_ESC4と同じ)
CONOUT5: pshs D,X,Y ;カーソルを画面の右下へ移動
ldd #$4F18
swi2
fcb $41,8 ;CURSET
puls D,X,Y
lbra CONOUT1
CONOUT6: pshs D,X,Y ;カーソルを表示
lda #$6E
swi2
fcb $41,4 ;SYCRST
puls D,X,Y
lbra CONOUT1
CONOUT7: pshs D,X,Y ;カーソルを非表示
lda #$2E
swi2
fcb $41,4 ;SYCRST
puls D,X,Y
lbra CONOUT1
CONOUT8: lbsr SPOUT ;カーソル位置にスペース出力
lbra CONOUT1
CONOUT_ESC: equ * ;ESCシーケンスの処理(単一引数の場合)
ldb ArgvCount ;引数の個数
lbne CONOUT_ESCM ;複数引数のESCシーケンス処理中はCONOUT_ESCM
cmpa #$3D ;=
lbeq CONOUT_ESC6 ;カーソル移動
cmpa #$2A ;*
lbeq CONOUT_ESC1 ;画面クリア
cmpa #$28 ;(
lbeq CONOUT_ESC2 ;反転文字
cmpa #$29 ;)
lbeq CONOUT_ESC3 ;反転文字解除
cmpa #$54 ;T
lbeq CONOUT_ESC4 ;カーソル位置から行末までクリア
cmpa #$59 ;Y
lbeq CONOUT_ESC5 ;カーソル以降画面クリア
clr ESC_ProcFlag
lbra CONOUT1
CONOUT_ESC1: pshs D,X,Y ;[ESC *] 画面を消去してカーソルをホームに移動
ldb #$00 ;消去範囲
lbsr CLSPRM
clr ESC_ProcFlag ;ESCシーケンス処理中クリア
puls D,X,Y
lbra CONOUT1
CONOUT_ESC2: pshs D,X,Y ;[ESC (] 反転文字に切替
ldd #$6C00 ;反転ビットオン
lbsr COLORW
clr ESC_ProcFlag ;ESCシーケンス処理中クリア
puls D,X,Y
lbra CONOUT1
CONOUT_ESC3: pshs D,X,Y ;[ESC )] 反転文字解除に切替
ldd #0x6400 ;反転ビットオフ
lbsr COLORW
clr ESC_ProcFlag ;ESCシーケンス処理中クリア
puls D,X,Y
lbra CONOUT1
CONOUT_ESC4: pshs D,X,Y ;[ESC T] カーソル位置から行末までクリア
swi2
fcb $41,75 ;CURSRD
CONOUT_E41: cmpa #$28 ;40
beq CONOUT_E42
lbsr SPOUT
inca
bra CONOUT_E41
CONOUT_E42: clr ESC_ProcFlag ;ESCシーケンス処理中クリア
puls D,X,Y
lbra CONOUT1
CONOUT_ESC5: pshs D,X,Y ;[ESC Y] カーソル位置から画面クリア
swi2
fcb $41,75 ;CURSRD
CONOUT_E51: cmpa #40 ;40桁
beq CONOUT_E52
lbsr SPOUT
inca
bra CONOUT_E51
CONOUT_E52: clra ;X=0
incb ;次の行
cmpb #24 ;24行
beq CONOUT_E53
clra ;X=0
bra CONOUT_E51
CONOUT_E53: clr ESC_ProcFlag ;ESCシーケンス処理中クリア
puls D,X,Y
lbra CONOUT1
CONOUT_ESC6: equ * ;カーソル移動
inc ArgvCount ;引数カウントインクリ
lbra CONOUT1
CONOUT_ESCM: equ *
leay LocateXY,PCR
ldb ArgvCount
cmpb #1
beq CONOUT_ESCM1
sta 1,Y ;YPos
ldd ,Y
pshs D,X,Y
swi2
fcb $41,8 ;CURSET
puls D,X,Y
clr ArgvCount
clr ESC_ProcFlag
lbra CONOUT1
CONOUT_ESCM1: sta ,Y ;XPos
inc ArgvCount
lbra CONOUT1
CONOUT_END: puls A,B,X,PC
CONOUT_SJIS: equ *
ldb SJIS_ProcFlag
bne CONOUT_SJ21 ;2バイト目の処理へ
ldb #$FF
stb SJIS_ProcFlag ;1バイト目ならフラグをセット
cmpa #$9F ;1バイト目の処理
bls CONOUT_SJ11 ;$9F以下なら SJ11
suba #$B1 ;それ以外なら
ldb #$02
mul
incb ;AccA*2->AccD+1
stb SJISCODE_H
lbra CONOUT1
CONOUT_SJ11:
suba #$71
ldb #$02
mul
incb ;AccA*2->AccD+1
stb SJISCODE_H
lbra CONOUT1
CONOUT_SJ21: cmpa #$7F
bcc CONOUT_SJ22 ;$7Fより大きいなら
bra CONOUT_SJ23
CONOUT_SJ22: deca ;AccA-1
CONOUT_SJ23: cmpa #$9E
bcc CONOUT_SJ24 ;$9E以上ならSJ24
suba #$1F
sta SJISCODE_L
bra CONOUT_SJ25
CONOUT_SJ24:
suba #$7D
sta SJISCODE_L
lda SJISCODE_H
inca
sta SJISCODE_H
CONOUT_SJ25:
ldd SJISCODE_H
std KNCODE
bsr KNPUT
clr SJIS_ProcFlag
lbra CONOUT1
SPOUT: pshs A ;スペース出力
lda #$20
lbsr OUTSCR
puls A,PC
KNPUT: pshs D,X,Y ;JIS漢字出力
bra KNPUT2
KNCODE: fdb $3441 ;JIS CODE
KNPARM: fcb $00 ;ERROR CODE
fcb $00 ;COMMAND CODE
fcb $00 ;NOT USE
fcb $00 ;PLOT OPTION
fdb $0000 ;NOT USE
fdb 0 ;HORIZONTAL POSITION
fdb 0 ;VIRTICAL POSITION
rmb 8 ;NOT USE
fdb $0001 ;HORIZONTAL OPTION(RATIO)
fdb $0001 ;VIRTICAL OPTOPN(RATIO)
fcb 1
fcb 2 ;PALETTE CODE(COLOR)
KNPARME: equ * ;PARAM END
KNPUT2: swi2
fcb $41,$69
ldx PIFBUF ;X=GRAPHIC I/F BUFFER
leay KNPARM,PCR ;PARAM POINTER
ldb #KNPARME-KNPARM
KNPUT3:
lda ,Y+
sta ,X+
decb
bne KNPUT3
KNPUT4:
ldd KNCODE,PCR
swi2
fcb $42,12
leay KNPARM,PCR
ldd 6,Y
addd #16
std 6,Y ;HORIZONTAL+16
cmpd #639
bls KNPUT6
ldd #0
std 6,Y
ldd 8,Y
addd #16 ;VARTICAL+16
std 8,Y
ldd 8,Y
cmpd #183
bcc KNPUT5
bra KNPUT6
KNPUT5: ldd #184
std 8,Y ;最終行固定(残件)
KNPUT6:
puls D,X,Y,PC
ESC_ProcFlag: rmb 1 ;ESC処理中フラグ
SJIS_ProcFlag: rmb 1 ;SJIS処理中フラグ
SJISCODE_H: rmb 1 ;SJIS漢字コード(H)
SJISCODE_L: rmb 1 ;SJIS漢字コード(L)
ArgvCount: rmb 1 ;引数カウント
LocateXY: rmb 2 ;カーソルXY
#+++ Lib
include ..\..\S1\kk_S1-Lib\S1Lib.asm
S1BASIC上ではすべての機能が動作していますがCP/MのBIOS09に組み込むとSJIS漢字出力は動作しませんでした。
(MBASICの問題かもしれません・・・)
10行目 エスケープシーケンスでLOCATE 10,11した後”AB”を表示。
20行目 “ABC”を表示した後、エスケープシーケンスで”DEF”を反転、”GHI”で反転解除
30行目 SJIS漢字コードで漢字を表示しようとしたが、Illeagal Function Callが発生
このIlleagal Function CallはMBASICが出したものではなくS1BASICが出しています。
ということは、この時点でCP/M80は終了しS1BASICに落ちています・・・
そんなCONOUT機能拡張の記録・・・^^