以前から動かして見たかったTEACのデジタルカセットデッキ MT-2を6809のPIA経由で汎用的に使えるドライバ(サブルーチン集)を作りました。
最初はS1で進める予定でしたMIDIプログラムがまだ中途半端でしたので、FM-77とPIAカードでMT-2に接続し実験しました
![]()
数年前に入手したMT-2デッキ、、、アルミケースに入ったDC電源内蔵のいい感じのデッキです(^^)
![]()
![]()
電源ユニットは2N3055使用の余裕の容量でトランス式なのでノイズ少なめでした。
MT-2は+5Vと+12Vが必要です
テープ走行検出エンコーダと思われるプーリーのゴムが傷んでいますがベタベタしていないのでまだ使えるようです![]()
これがピンチローラならテープ送りは無理そうですがテープ走行のエンコーダのようなのでこの状態でも大丈夫のようです(^^;;;
FM77とのインターフェースはold68funさんから頂いたPIA基板を使い、そこからMT-2用にインバータを入れています。![]()
ソフトのデバッグ用にLEDのデバッガーも追加しました(^^)
このLEDのデバッガですが思った以上にソフトのデバッグに役立ちました。
みなさんもどうぞ・・・
回路はこんな感じでデータバスのゲートは#CSでゲートしても、GNDで常に通過でも正常に動作するようです。
![]()
old68funさんのPIAカードのアドレスは$FD9C~です。
S1やレベル3で使う場合、ここをMP-1895カードの$FF60に変えるだけでいける想定です。
FM-77の横に置いても邪魔にならないコンパクトな筐体(^^)
![]()
デザインはPROLINE-100の方がカッコいいですが、コンパクトなのでデバッグ用にはいいですね。
処理内容はTEAC公式のサンプルプログラムを流用したものでPIA経由の処理(CMTC_WRITEとCMTC_READ)以外はTEAC公式のプログラムと同じ処理内容です。
そのため、WRITERとLOADERの機能も全く同じものです。
TEAC公式のものは6800用のコードだったので、6809のニーモニックに置き換えています。
TEACのLOADERは保存時に記録したアドレスに戻すことしかできないのでオフセットを指定できるようにしています。
S1でもFMでも汎用的に使いたいのでPIA経由にしました。
また、そのまま持ってこれるように各サブルーチンは位置独立になっています。
ソースコードはこちらです。
アセンブラはいつものシステムロード SASMです
使い方は最初にMT2_INITを一回実行して、
SAVEはFSTADに保存したいメモリの先頭番地をセットして、
ENDADに終了番地+1をセットしMT2_WRITE_TOPを実行するとSAVEできます
LOADはLDOFSにテープに保存した番地からメモリにロードするオフセットをセットしてMT2_READ_TOPを実行するとテープからメモリにロードされます。
このプログラムはファイル管理していないので、テープの先頭から1個のファイルが保存されるだけの簡単な機能のみでファイル名などはありません。
ファイル名をつけるにはTOSなどの上位層のプログラムが必要です。
;MT2Driver2.ASM
PAGE 999
;=======================================================================
; MT2Driver2 TEAC MT-2 デジタルカセット ドライバ(PIA接続・位置独立) Rev.0
;-----------------------------------------------------------------------
; PIAのレジスタ(PIAベース番地からの相対)
PA_DATA EQU 0 ;ポートA データ/DDR
PA_CTRL EQU 1 ;ポートA コントロール
PB_DATA EQU 2 ;ポートB データ/DDR
PB_CTRL EQU 3 ;ポートB コントロール
; ワーク(Uが先頭)
FSTAD EQU 0 ;先頭番地(ヘッダとしてテープに記録)
ENDAD EQU 2 ;最終番地+1
LDOFS EQU 4 ;読込みオフセット
MEMPTR EQU 6 ;
LIMIT EQU 8 ;
TRY EQU 10 ;
PIABASE EQU 11 ;
MT2_WORK_SIZE EQU 13 ;
; MT-2レジスタ番号 (RS2-RS0)
DBR EQU 0 ;データバッファ
WDC EQU 1 ;ワードカウンタ(0=256バイト)
CDR EQU 2 ;コマンド
MDR0 EQU 3 ;モード0
CSR EQU 4 ;カセットステータス
ESR EQU 5 ;エラーステータス
ISR EQU 6 ;割込みステータス
; MT-2コマンド
CMD_IM EQU $C0
CMD_WRT EQU 1 ;1ブロック書込み
CMD_WTM EQU 2 ;テープマーク書込み
CMD_ERA EQU 3 ;消去
CMD_RDL EQU 4 ;1ブロック読出し
CMD_RDH EQU 5 ;1ブロック読出し(読戻し確認用。判定が厳しい)
CMD_REV EQU 7 ;1ブロック逆送り
CMD_SLP EQU 8 ;ロードポイント設定
CMD_SLE EQU 9 ;ロードポイント設定(消去付き)
CMD_REW EQU 10 ;巻戻し
CMD_STM EQU 12 ;テープマーク検索
ISR_CCE EQU %10000000 ;コマンド終了
ISR_DBRE EQU %01000000 ;DBRが空(書込み要求)
ISR_DA EQU %00100000 ;読出しデータあり
CSR_ERR EQU %10000000 ;エラー(ESRのどれかが1)
MDR0_INIT EQU %00010010 ;MDR0の通常値(固定ビットb4,b1。DMA不使用)
MDR0_SRST EQU %10000000 ;ソフトウェアリセット
HDR_SIZE EQU 4 ;ヘッダのバイト数
RETRY_MAX EQU 4 ;書直し/再読込みの回数(ブロック毎)
RES_OK EQU 1 ;正常
RES_WRITE_ERR EQU $FE ;書込みエラー
RES_READ_ERR EQU $FF ;読込みエラー
; PIAの設定
PIA_CR_DDR EQU %00000000 ;コントロール: DDRアクセス
PIA_CR_DATA EQU %00000100 ;コントロール: データレジスタアクセス
PIA_IN EQU $00 ;DDR: 全入力
PIA_OUT EQU $FF ;DDR: 全出力
BIT_RW EQU %00001000 ;PB3 R/#W (1=読出し)
BIT_CS EQU %00010000 ;PB4 CS
BIT_CSX EQU %11101111 ;CSだけを落とすマスク
BIT_E EQU %00100000 ;PB5 E
RS_MASK EQU %00000111 ;PB2-PB0 RS
;------------------------------------------------------------
; ENTRY
;------------------------------------------------------------
ORG $6000
MT2D_BASE: LBRA USR_ENTRY ;+0
FCB 0 ;+3 Rev.No
FCC "MT2S" ;+4
LBRA MT2_INIT ;+8
LBRA MT2_WRITE_TOP ;+11
LBRA MT2_WRITE_NEXT ;+14
LBRA MT2_READ_TOP ;+17
LBRA MT2_READ_NEXT ;+20
LBRA MT2_ABORT ;+23
LBRA MT2_REV ;+26
USR_ENTRY: RTS
; 初期化
MT2_INIT: STD PIABASE,U
CLR LDOFS,U
CLR LDOFS+1,U
LBRA MODE_SET
;============================================================
; WRITER
;============================================================
MT2_WRITE_TOP: LBSR MODE_SET
LDA #CMD_IM+CMD_REW
LBSR CMD_RUN
LDA #CMD_IM+CMD_SLE
LBSR CMD_RUN
BRA WRITE_FILE
MT2_WRITE_NEXT: LBSR MODE_SET
; ヘッダ → データ(最後のブロックまで) → ERA → TM
WRITE_FILE: LEAX FSTAD,U ;ヘッダはワークのFSTAD,ENDADをそのまま書く
STX MEMPTR,U
LEAX HDR_SIZE,X
STX LIMIT,U
LBSR WRITE_BLOCK
BCS WF_ERR
LDX FSTAD,U
STX MEMPTR,U
WF_DATA: LBSR BLOCK_LIMIT
PSHS A ;A=0なら最後のブロック
LBSR WRITE_BLOCK
PULS A
BCS WF_ERR
TSTA
BNE WF_DATA
LDA #CMD_IM+CMD_ERA
LBSR CMD_RUN
LDA #CMD_IM+CMD_WTM
LBSR CMD_RUN
LDB #RES_OK
RTS
WF_ERR: LDB #RES_WRITE_ERR
RTS
; 1ブロック書込み → 読戻して確認しエラーなら書直し
; 戻り値: C=0 正常(MEMPTR=LIMIT) C=1 回数オーバー
WRITE_BLOCK: LDA #RETRY_MAX
STA TRY,U
WB_AGAIN: LBSR STATUS_CLEAR
LDA #CMD_IM+CMD_WRT
LBSR BLOCK_START
LDX MEMPTR,U
WB_FEED: LDY #ISR
LBSR CMTC_READ
BITA #ISR_CCE
BNE WB_END
BITA #ISR_DBRE
BEQ WB_FEED
CLRA
CMPX LIMIT,U
BHS WB_PUT ;有効データを送り終えた
LDA ,X+
WB_PUT: LDY #DBR
LBSR CMTC_WRITE
BRA WB_FEED
WB_END: LBSR BLOCK_VERIFY
LBSR STATUS_ERR
BCC WB_OK
LBSR RETRY_STEP ;エラー
BCC WB_AGAIN
RTS
WB_OK: LDX LIMIT,U
STX MEMPTR,U
ANDCC #$FE
RTS
; 照合(RDHで読み、CRC等の判定はMT-2が行う)
BLOCK_VERIFY: LBSR MT2_REV
LBSR STATUS_CLEAR
LDA #CMD_IM+CMD_RDH
LBSR BLOCK_START
BV_LOOP: LDY #ISR
LBSR CMTC_READ
BITA #ISR_CCE
BNE BV_END
BITA #ISR_DA
BEQ BV_LOOP
LDY #DBR
LBSR CMTC_READ
BRA BV_LOOP
BV_END: RTS
;============================================================
; LOADER
;============================================================
MT2_READ_TOP: LBSR MODE_SET
LDA #CMD_IM+CMD_REW
LBSR CMD_RUN
LDA #CMD_IM+CMD_SLP
LBSR CMD_RUN
BRA READ_FILE
MT2_READ_NEXT: LBSR MODE_SET
LDA #CMD_IM+CMD_STM
LBSR CMD_RUN
READ_FILE: LEAX FSTAD,U
STX MEMPTR,U
LEAX HDR_SIZE,X
STX LIMIT,U
LBSR READ_BLOCK
BCS RF_ERR
LDD FSTAD,U ;読込み先 = 記録された番地 + LDOFS
ADDD LDOFS,U
STD FSTAD,U
LDD ENDAD,U
ADDD LDOFS,U
STD ENDAD,U
LDX FSTAD,U
STX MEMPTR,U
RF_DATA: LBSR BLOCK_LIMIT
PSHS A ;A=0なら最後のブロック
LBSR READ_BLOCK
PULS A
BCS RF_ERR
TSTA
BNE RF_DATA
LDB #RES_OK
RTS
RF_ERR: LDB #RES_READ_ERR
RTS
; 1ブロック読込み(リトライあり)
; 戻り値: C=0 正常(MEMPTR=LIMIT) C=1 回数オーバー
READ_BLOCK: LDA #RETRY_MAX
STA TRY,U
RB_AGAIN: LBSR STATUS_CLEAR
LDA #CMD_IM+CMD_RDL
LBSR BLOCK_START
LDX MEMPTR,U
RB_LOOP: LDY #ISR
LBSR CMTC_READ
BITA #ISR_CCE
BNE RB_END
BITA #ISR_DA
BEQ RB_LOOP
LDY #DBR
LBSR CMTC_READ
CMPX LIMIT,U
BHS RB_LOOP
STA ,X+
BRA RB_LOOP
RB_END: LBSR STATUS_ERR
BCC RB_OK
LBSR RETRY_STEP
BCC RB_AGAIN
RTS
RB_OK: LDX LIMIT,U
STX MEMPTR,U
ANDCC #$FE
RTS
;============================================================
; WRITER/LOAADER共通
;============================================================
; データブロックのLIMITを決める。
; 戻り値 A=0:これが最後のブロック(残り256バイト未満) A≠0:続きがある
BLOCK_LIMIT: LDD ENDAD,U
SUBD MEMPTR,U ;D=残りのバイト数
TSTA
BEQ BL_LAST
LDX MEMPTR,U
LEAX 256,X
STX LIMIT,U
RTS
BL_LAST: LDX ENDAD,U
STX LIMIT,U
RTS
; 書直し/再読込みの準備
RETRY_STEP: LDA TRY,U
BEQ RS_OVER
DEC TRY,U
LBSR MT2_REV
ANDCC #$FE
RTS
RS_OVER: ORCC #1
RTS
; 1ブロックの転送開始
BLOCK_START: PSHS A
CLRA
LDY #WDC
LBSR CMTC_WRITE
PULS A
LDY #CDR
LBSR CMTC_WRITE
RTS
; コマンドAを発行し、完了(CCE)を待つ
CMD_RUN: LDY #CDR
LBSR CMTC_WRITE
CR_WAIT: LDY #ISR
LBSR CMTC_READ
BITA #ISR_CCE
BEQ CR_WAIT
RTS
; CSRとESRを読んでエラー状態を消す
STATUS_CLEAR: LDY #CSR
LBSR CMTC_READ
LDY #ESR
LBSR CMTC_READ
RTS
; CSRを読み、エラーがあればC=1
STATUS_ERR: LDY #CSR
LBSR CMTC_READ
ANDA #CSR_ERR
BNE SE_ERR
ANDCC #$FE
RTS
SE_ERR: ORCC #1
RTS
MODE_SET: LDA #MDR0_INIT
LDY #MDR0
LBSR CMTC_WRITE
RTS
; テープを1ブロック戻す
MT2_REV: LDA #CMD_IM+CMD_REV
LBSR CMD_RUN
RTS
; コマンド中断: SRST(ソフトウェアリセット)を送り、MDR0を通常値に戻す
MT2_ABORT: LDA #MDR0_INIT+MDR0_SRST
LDY #MDR0
LBSR CMTC_WRITE
LBSR MODE_SET
RTS
;================================================================================
; PIAアクセス (Y=MT-2レジスタ番号、U=ワーク。A,Y以外は保存)
; CMTC_WRITE: A=書込みデータ
; CMTC_READ: 戻り値 A=読出しデータ
; MT-2の書込みは「E後縁でデータ取込み → 次のE前縁(CS解除中)でレジスタへ反映」の順で完了する。
; PIAはアクセス時にしかEが出ないため、書込みの最後にCS解除のままEをもう1回出して補う必要あり。
;===============================================================================
CMTC_WRITE: PSHS Y,B
LDB 2,S ;B=レジスタ番号
LDY PIABASE,U ;Y=PIAベース番地
PSHS A
LDA #PIA_CR_DDR
STA PA_CTRL,Y
LDA #PIA_OUT
STA PA_DATA,Y ;PA=出力
LDA #PIA_CR_DATA
STA PA_CTRL,Y
CLRA
STA PA_DATA,Y
LDA #PIA_CR_DDR
STA PB_CTRL,Y
LDA #PIA_OUT
STA PB_DATA,Y ;PB=出力
LDA #PIA_CR_DATA
STA PB_CTRL,Y
CLRA
STA PB_DATA,Y ;CS解除、E=Low
PULS A
STA PA_DATA,Y ;書込みデータ
ANDB #RS_MASK
ORB #BIT_CS
STB PB_DATA,Y ;RSとCSを確定
NOP
ORB #BIT_E
STB PB_DATA,Y ;E=High
NOP
NOP
EORB #BIT_E
STB PB_DATA,Y ;E=Low(この後縁でMT-2がデータを取込む)
NOP
ANDB #BIT_CSX
STB PB_DATA,Y ;CS解除
ORB #BIT_E
STB PB_DATA,Y ;ダミーE: High
NOP
NOP
EORB #BIT_E
STB PB_DATA,Y ;ダミーE: Low
PULS B,Y
RTS
CMTC_READ: PSHS Y,B
LDB 2,S ;B=レジスタ番号
LDY PIABASE,U ;Y=PIAベース番地
LDA #PIA_CR_DDR
STA PA_CTRL,Y
LDA #PIA_IN
STA PA_DATA,Y ;PA=入力
LDA #PIA_CR_DATA
STA PA_CTRL,Y
CLRA
STA PA_DATA,Y
LDA #PIA_CR_DDR
STA PB_CTRL,Y
LDA #PIA_OUT
STA PB_DATA,Y ;PB=出力
LDA #PIA_CR_DATA
STA PB_CTRL,Y
LDA #BIT_CS
STA PB_DATA,Y
NOP
ANDB #RS_MASK
ORB #BIT_RW+BIT_CS
STB PB_DATA,Y ;RS,CS,R/#W=読出しを確定
NOP
ORB #BIT_E
STB PB_DATA,Y ;E=High(MT-2がデータを出力)
NOP
NOP
LDA PA_DATA,Y ;データ取込み
EORB #BIT_E
STB PB_DATA,Y ;E=Low(ISR/ESRのフラグはここで消える)
NOP
ANDB #BIT_CSX
STB PB_DATA,Y ;CS解除
PULS B,Y
RTS
ENDこのドライバーだけでメモリ内のデータをデジタルカセットに記録と保存ができるようになりました。
確かに普通のデータレコーダとは比べものにならないほど高速です。
また、記録時は256バイト書込んだ後にベリファイの為1ブロック巻き戻して読込みするので、
大型の9トラックMTのようなテープ送りも楽しめます(^^)
試しに普通のオーディオ用カセットテープでも記録と再生を試してみましたが、特段問題なく読み書きできました。
これを応用してTOSに格上げするともっと楽しめそうですね。
S1やレベル3にもTOSが完成したら、新品で確保しているMT-2の出番がきそうです(^^)
中古で入手したPROLINE-100も物置にあったはずなので、持ってきてO/HしたいところですがPROLINE-100は走行エンコーダプーリのゴムが完全に無くなっていたと思うのでそのままでは動作しないと思われます・・・
現在はold68funさんのFLEX9用ROM/RAMDISKボードも接続してお大尽システムになっているのでFLEX9の環境でもMT-2を動作できるようにソフトを作りたいですね・・(^^;;;
![]()
Nostalgic Roomさんから頂いたFDDのSELECT信号切替スイッチを利用してGOTEKと内蔵3.5、外付け5インチのどこからでも起動できるので最高に使いやすいFM-77になっています。
これでMT-2も接続できればFM-77環境もいい感じで仕上がりそうです(^^)
そんなFM-77にTEAC MT-2 デジタルカセット接続の記録・・・