プログラミング
Memo-1: Minitelをターミナルとして使用した、ゼロから構築された6502コンピュータ
Memo-1: A 6502 computer built from scratch, using a Minitel as its terminal (github.com)
要約
Benoit Aveline氏が、学習目的でゼロから構築した65C02ベースのコンピュータ「Memo-1」を紹介しています。このシステムは1MHzで動作する65C02 CPU、32KBのRAM、16KBのROMを備え、Minitel 1bをターミナルとして使用します。ジョイスティックポートや音を鳴らす機能も搭載されており、WOZMONやMS-BASICなどのソフトウェアを実行できます。記事では、ハードウェア構成、アドレス指定、外部スロット、VIAおよびACIAの機能、そしてコードの組み立て方法について詳細に解説しています。
全文翻訳
Memo-1 楽しみと学習のために、シンプルな65C02ベースのコンピュータを作成しました。部品表と組み立て手順は、ROMと共にここにあります。
技術情報
Memo-1は、1MHzで動作する65C02 CPU、粗雑に接続された32KBのRAM、16KBのROM、および6551 ACIA(W65C51ではない)で構成されています。システムは、拡張用に8KBのROMが利用可能であり、ターミナルとしてMinitel 1bにリンクされることを想定しています。
アドレス
High nibble (A15..A12) | Hex range | Selection
-----------------------+----------------+-----------------
0000 (0x0) | 0000 - 0FFF | RAM
0001 (0x1) | 1000 - 1FFF | RAM
0010 (0x2) | 2000 - 2FFF | RAM
0011 (0x3) | 3000 - 3FFF | RAM
0100 (0x4) | 4000 - 4FFF | RAM
0101 (0x5) | 5000 - 5FFF | RAM
0110 (0x6) | 6000 - 6FFF | RAM
0111 (0x7) | 7000 - 7FFF | RAM
-----------------------+----------------+-----------------
1000 (0x8) | 8000 - 8FFF | VIA
1001 (0x9) | 9000 - 9FFF | ACIA
-----------------------+----------------+-----------------
1010 (0xA) | A000 - AFFF | External slot
1011 (0xB) | B000 - BFFF | External slot
-----------------------+----------------+-----------------
1100 (0xC) | C000 - CFFF | ROM
1101 (0xD) | D000 - DFFF | ROM
1110 (0xE) | E000 - EFFF | ROM
1111 (0xF) | F000 - FFFF | ROM
外部スロット
外部スロットは、フルCPUバスを露出する32ピンコネクタ(J4)です。
Pin | Signal Pin | Signal
----+--------- ----+---------
1 | A0 2 | D0
3 | A1 4 | D1
5 | A2 6 | D2
7 | A3 8 | D3
9 | A4 10 | D4
11 | A5 12 | D5
13 | A6 14 | D6
15 | A7 16 | D7
17 | A8 18 | GND
19 | A9 20 | /Ext select
21 | A10 22 | CLK
23 | A11 24 | /IRQ
25 | A12 26 | /NMI
27 | A13 28 | /RES
29 | A14 30 | R/W
31 | A15 32 | +5V
奇数ピンはアドレスバス(A0–A15)、偶数ピン2–16はデータバス(D0–D7)を運び、残りの偶数ピンは制御信号を運びます。
/Ext select信号は、CPUが $A000–$BFFF のアドレスにアクセスしたときにアサートされます。これは、外部ROMからコードを実行するために使用できます(コードはA000からBFFFの間で実行されるようにコンパイルする必要があります)。また、カセットテープ拡張(使用している標準ではKCSとして参照)のスロットでもあります。この拡張により、BASICでコードを保存/ロードしたり、アドレス空間のどこからでもコードの生のダンプを保存/ロードしたりできます。
VIA
65C22 VIAはアドレス $8000 から $8003 でアクセス可能で、割り込みをトリガーすることはできません。これは2つのAtari CX40ジョイスティックポートを提供するために使用されます。
VIAアドレス
Port B RW ------------------ $8000
Port A RW ------------------ $8001
Data direction register B -- $8002
Data direction register A -- $8003
Timer 1 low byte ----------- $8004
Timer 1 high byte ---------- $8005
Auxiliary Control Register - $800B
Atari 2600ジョイスティック0はVIA Port Aビット[0..4]に、ジョイスティック1はVIA Port Bビット[0..4]に以下のように接続されます。
Up ----- Bit0
Down --- Bit1
Left --- Bit2
Right -- Bit3
Fire --- Bit4
BASIC関数
JOY()は同じ機能を提供します。ポートAの場合はJOY(0)、ポートBの場合はJOY(1)は、指定されたポートのステータスに対応する数値を返します(この方法で、ビット5、6、7は、この実装を変更せずに将来使用できます)。
例:
10 A = JOY(0)
20 IF A = 31 THEN GOTO 10
30 IF A = 30 THEN PRINT "UP"
40 IF A = 29 THEN PRINT "DOWN"
50 IF A = 27 THEN PRINT "LEFT"
60 IF A = 23 THEN PRINT "RIGHT"
70 IF A = 15 THEN PRINT "FIRE"
80 GOTO 10
RUN
TONEはPort Bビット7で方形波トーンを再生します。ここでは1MHzでの各ノートの換算表です。
DO 261.63Hz = 1911
DO# 277.18Hz = 1808
RE 293.66Hz = 1702
RE# 311.13Hz = 1607
MI 329.63Hz = 1517
FA 349.23Hz = 1432
FA# 369.99Hz = 1350
SOL 392.00Hz = 1275
SOL# 415.30Hz= 1203
LA 440Hz = 1136
LA# 466.16Hz = 1073
SI 493.88Hz = 1010
LA 440Hzの音をしばらく鳴らしてからTONE 0で停止します。
10 TONE 1136
20 K = 40
30 FOR I=0 TO K STEP 1
40 PRINT I
50 NEXT I
60 TONE 0
70 END
RUN
ACIA
ACIAデータレジスタ ----- $9000
ACIAステータスレジスタ --- $9001
ACIAコマンドレジスタ -- $9002
ACIAコントロールレジスタ -- $9003
メニュー
起動時、src/startup.sコードがシステムを初期化し、ブートメニューを表示します。Memo-1はACIA、VIAを初期化し、Minitelにボーレートを変更してローカルエコーを無効にするコマンドを送信し、その後いくつかのオプションを持つシンプルなメニューシステムを表示します。'1'を押すとWOZMON(メモリの検査と変更のためのSteve Wozniakによるモニタープログラム)が起動し、'2'を押すとMS-BASIC(Microsoft BASICインタプリタ)が起動し、'3'を押すと外部ROMスロットからコードを実行します(このオプションは外部ROMがアドレス $A000 で検出された場合にのみ表示されます)、または'A'を押すとシステム情報、ライセンス、クレジットが表示されるアバウト画面が表示されます。メニューは、 $A000 の最初のオペコードを調べることで、外部ROMの存在を自動的に検出し、利用可能なオプションを適応させます。もし $A0 を読み取った場合、何も存在しないと仮定します(6502は、ハードウェアが応答しないアドレスにアクセスする際に常にアドレスの高位ニブルを読み取ります)。スタートメニューが外部スロットにROMを検出した場合、ROMの最初の8バイト、 $A000 から $A007 にあるヘッダーからパーソナライズされた名前を読み取ります。メニューエントリは $A008 にジャンプします。
ターミナル
このプロジェクトは、Minitel 1bをターミナルとして使用するために作られています。6551 ACIAチップをUARTとして使用することを想定した、65C02用のシンプルなMinitelドライバを実装しています(Minitelと2つのハードウェア非互換性があるW65C51ではありません)。Minitelドライバは src/minitel.s ファイルです(ええ、私が家族の中で風変わりな方です)。
プリンター
Minitelプリンターのサポートはまだ開発中です。
コードの組み立て
コードはca65およびld65アセンブラとリンカを使用するように構築されています。自分でコードをアセンブルするには、両方のバイナリがパスにあることを確認するか、以下のコマンドを適応させてください。まず、srcの隣にoutディレクトリがあることを確認してください。このリポジトリをクローニングした場合、バイナリリリースを共有したかったので、すでに持っているはずです。
cd src
ca65 -D memo msbasic.s -o ../out/memo.o
ld65 -C memo.cfg ../out/memo.o -o ../out/memo.bin -Ln ../out/memo.lbl
longbranch.macが含まれていないというエラーが発生した場合は、asmincフォルダを含める必要があります。例:
ca65 -I /usr/local/cc65/share/cc65/asminc -D memo msbasic.s -o ../out/memo.o
ライセンスとクレジット
65C02チップセットベースのコンピュータ。楽しみと学習目的のため。Benoit Aveline(別名Memoire Morte)著(c)2025 - Creative Commons BY-NC-SA
特別な感謝:
Ben Eater氏の6502コンピュータ設計とチュートリアルに感謝 - CC-BYライセンス
Ian Ward氏の2004 LCDと555タイマーに関するYouTube動画に感謝 - ライセンスは見つかりませんでした
現在のソースコードは以下に基づいています:
Wozmon by Steve Wozniak - (c) 1976 Apple(コードIPが存在する前)
BASIC-M6502 by Weiland & Gates - (c) Microsoft - MITライセンス
MS-BASICの逆アセンブリ by Michael Steil - 2-clause BSDライセンス