PC-8001の仕様とN80の構造について
last modified: Aug, 22, 2007
PC-8001はCPUにZ80互換のNEC製uPD780C 4MHz、CMTコントローラ(カセットテープ)、USART(i8251)、CRTC(uPD3301)、DMAC(i8257)、カレンダー(uPD1990)などから構成されています。
ROM(24KB) |
|||
未使用
|
|
||
RAM
|
|
||
PORT
|
TYPE
|
I/O
|
b7
|
b6
|
b5
|
b4
|
b3
|
b2
|
b1
|
b0
|
備考
|
00H
|
KEYBOARD SCAN |
I
|
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
|
01H
|
I
|
RT
|
.
|
,
|
=
|
+
|
*
|
9
|
8
|
||
02H
|
I
|
G
|
F
|
E
|
D
|
C
|
B
|
A
|
@
|
||
03H
|
I
|
O
|
N
|
M
|
L
|
K
|
J
|
I
|
H
|
||
04H
|
I
|
W
|
V
|
U
|
T
|
S
|
R
|
Q
|
P
|
||
05H
|
I
|
=
|
^
|
]
|
¥
|
[
|
Z
|
Y
|
X
|
||
06H
|
I
|
7'
|
6&
|
5%
|
4$
|
3#
|
2"
|
1!
|
0
|
||
07H
|
I
|
_
|
?
|
>
|
<
|
;
|
:
|
9)
|
8(
|
||
08H
|
I
|
CT
|
SF
|
カナ
|
GR
|
DL
|
←
|
↑
|
HM
|
||
09H
|
I
|
EC
|
SP
|
F5
|
F4
|
F3
|
F2
|
F1
|
ST
|
||
10H
|
CALENDER
|
O
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
|
20H
|
USART(8251)
|
I/O
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
|
21H
|
I/O
|
STOP
|
EO
|
PN
|
LEN
|
CLK
|
|||||
−
|
IR
|
RS
|
ER
|
BK
|
TE
|
DR
|
RE
|
||||
30H
|
CONTROL PORT#1 |
O
|
−
|
−
|
CB2/1
|
MT
|
CI
|
CL
|
WD
|
||
0
|
0
|
||||||||||
0
|
1
|
||||||||||
1
|
0
|
||||||||||
1
|
1
|
||||||||||
*
|
|||||||||||
*
|
|||||||||||
*
|
|||||||||||
40H
|
CONTROL PORT#2 |
I
|
−
|
−
|
VR
|
DI
|
EX
|
CD
|
AK
|
BY
|
|
*
|
|||||||||||
*
|
|||||||||||
*
|
|||||||||||
*
|
|||||||||||
*
|
|||||||||||
*
|
|||||||||||
O
|
−
|
−
|
−
|
BP
|
DS
|
CK
|
TB
|
ST
|
|||
*
|
|||||||||||
*
|
|||||||||||
*
|
|||||||||||
*
|
|||||||||||
*
|
|||||||||||
50H
|
CRTC
|
O
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
|
51H
|
O
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
||
64H
|
DMAC
|
O
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
|
65H
|
O
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
||
68H
|
I/O
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
本体パラレルポートは34pinのカードエッジ
┌───────────────────────────┐
│ 33 31 29 27 25 23 21 19 17 15 13 11 9 7 5 3 1 │
│−〓-〓-〓-〓-〓-〓-〓-〓-〓-〓-〓-〓-〓-〓-〓-〓-〓−│
│ 34 32 30 28 26 24 22 20 18 16 14 12 10 8 6 4 2 │
└───────────────────────────┘
G B D7 D6 D5 D4 D3 D2 D1 D0 S
B:BUSY(IN)、S:STROBE(OUT)、G:GND、D0〜D7:データ(OUT)
作業には上記のようなエッジコネクタ/パラレルポート間ケーブルを作成してPC-8001と互換機を接続しました。
TYPE
|
b7
|
b6
|
b5
|
b4
|
b3
|
b2
|
b1
|
b0
|
備考
|
モノクロ
|
TG
|
−
|
下
|
上
|
−
|
反
|
点
|
消
|
|
カラー
|
緑
|
赤
|
青
|
TG
|
1
|
−
|
−
|
−
|
|
−
|
−
|
下
|
上
|
0
|
反
|
点
|
消
|
キャラクタージェネレータ部とi8253タイマーより構成されている。キャラクタージェネレータは本体フォントのASCIIコード(128〜255)までの128文字分のフォントに対して操作でき、キャラクタージェネレータ用に1KB(128文字×8byte)のRAMが搭載されている(フォントデータ1文字分は8byte)。音声はi8253のch.0がPCGのスピーカーに接続され効果音を出力する(他のch.1、ch.2は未使用)。i8253には4MHzのCLKが入力されている。
PORT
|
TYPE
|
I/O
|
b7
|
b6
|
b5
|
b4
|
b3
|
b2
|
b1
|
b0
|
備考
|
00H
|
キャラクタ ジェネレータ |
O
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
|
01H
|
O
|
A7
|
A6
|
A5
|
A4
|
A3
|
A2
|
A1
|
A0
|
||
02H
|
O
|
−
|
−
|
MC
|
CL
|
SP
|
−
|
A9
|
A8
|
||
*
|
1:COPY 本体FONT ROMの内容を内部RAMに転送 |
||||||||||
*
|
|||||||||||
*
|
|||||||||||
0CH
|
i8253
|
O
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
|
0DH
|
O
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
||
0EH
|
O
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
||
0FH
|
O
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
(ワード転送、方形波、バイナリーで36Hを設定) |
メモリ中のN-BASICの格納形式について
$EB54にN-BASICプログラム格納メモリのスタート番地が入っており、32KB RAMの場合はスタート番地は$8021である。以下の形式でN-BASICプログラム本体が格納されている。
ADDR
|
NEXT
|
LINE
|
BASIC
|
EOL
|
||
29
|
80
|
LO
|
HI
|
中間言語
|
00
|
|
72
|
80
|
LO
|
HI
|
中間言語
|
00
|
|
00
|
00
|
00
|
00
|
外部記憶装置として高価なフロッピーディスクよりもオーディオ用のカセットテープがよく使われていました。デジタルデータを音声に変調して録音することで記憶させていたのですが、ここではそのフォーマットについて記載しておきます。尚、N80で利用されるCMT形式のファイルも、このCMTフォーマットで記録されたテープの内容そのままをファイル化したものです。
モニタからセーブ、ロードされるテープのフォーマットです。
ヘッダー
|
データブロック#1
|
〜
|
データブロック#N
|
終了
|
|||||||||||
3A
|
HI
|
LO
|
CK
|
3A
|
LN
|
データ
|
CK
|
3A
|
LN
|
データ
|
CK
|
3A
|
00
|
00
|
BASICからセーブ、ロードされるテープのフォーマットです。
ヘッダー(D3×9)
|
ファイル名(6文字)
|
本体
|
終了(00×9)
|
||||||||||||||||||||
D3
|
D3
|
D3
|
D3
|
D3
|
D3
|
D3
|
D3
|
D3
|
**
|
**
|
**
|
**
|
**
|
**
|
00
|
00
|
00
|
00
|
00
|
00
|
00
|
00
|
N80形式ファイルとはN80エミュレータで使用されるイメージファイルで拡張子はN80(*.N80)です。N80形式はある瞬間のRAMの状態をそのままに僅かな補助情報を加えてダンプ出力したファイルです。これは実機にてテープからゲームなどをロードした直後にRAMの内容をほぼそのままパラレルポートより互換機に転送していたのに由来するファイル形式で、実機側のマシン状態情報は持っていません。初期の頃はPC-8001のみで作業をしていたので、このようなアバウトな仕様になっています(メモリに余裕のあるPC-8801では主にCMT形式で抽出するようになりましたが…)。従って、このN80形式のファイルは電源投入後の状態(桁数やカラー/モノクロ)のままで作業する必要があります。
実機のパラレル転送プログラムは未使用の領域$FF3Dから格納されており、スタート番地は$FF40です。実機にてゲームをcloadやモニタのLコマンドにてロードした後に$FF40から転送プログラムを実行すると、その時点でのSPの値が$FF3Eに格納されRAMの領域$8000〜$FF3Fがパラレルポート経由で互換機へと転送されます:
ADDR| +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
----+--------------------------------------------------
FF30: ** ** ** ** ** ** ** ** - ** ** ** ** ** C9 00 00
FF40: ED 73 3E FF 21 00 80 DB - 40 E6 01 28 FA 7E D3 10
FF50: AF D3 40 DB 40 E6 01 20 - FA 3E 01 D3 40 23 7C FE
FF60: FF 20 E4 7D FE 40 20 DF - 2A 34 FF C9 ** ** ** **
;
; PC-8001 側転送ルーチン
; ------------------------------
; AREA: $FF3D-$FF6B
; 開始: $FF40
; 機能: $8000-$FF3F を転送する
;
FF3D C9 RET ; エミュレータPC位置
FF3E 00 00 DW 0000h ; save SP buffer
FF40 ED 73 3E FF LD (FF3Eh),SP ; 現在の SP 待避
FF44 21 00 80 LD HL,8000h ; 転送開始番地
FF47 DB 40 wait1: IN A,(40h) ; BUSY="H" を確認
FF49 E6 01 AND 01h ;(相手方受信可能通知)
FF4B 28 FA JR Z,wait1
FF4D 7E LD A,(HL) ; データ出力
FF4E D3 10 OUT (10h),A
FF50 AF XOR A ; データ出力通知(PSTB="L")
FF51 D3 40 OUT (40h),A
FF53 DB 40 wait2: IN A,(40h) ; BUSY="L" を確認
FF55 E6 01 AND 01h ;(相手方受信完了通知)
FF57 20 FA JR NZ,wait2
FF59 3E 01 LD A,01h ; 転送終了告知(PSTB="H")
FF5B D3 40 OUT (40h),A
FF5D 23 INC HL ; 転送番地更新
FF5E 7C LD A,H ; 転送終了番地チェック
FF5F FE FF CP FFh
FF61 20 E4 JR NZ,wait1
FF63 7D LD A,L
FF64 FE 40 CP 40h
FF66 20 DF JR NZ,wait1
FF68 2A 34 FF LD HL,(FF34h) ; BASIC に戻る(^B)
FF6B C9 RET
これをそのままバイナリファイルとして保存したものがN80形式です。N80ではN80形式のファイルをエミュレータのRAMに読み込み$FF3Eに格納されたSPの値をエミュレータのSPレジスタにセットし、PCを$FF3Dに設定します。$FF3DはZ80のコード"RET"となっていますから、実機にて転送を行った時点の状態から復帰するような動きが再現されます(各レジスタの値は不定ですが、特に問題なかったのでw)。
即ち、N80ファイル形式とはメモリの$8000〜$FF3Fまでがダンプされ、$FF3D(ファイル中でのオフセットは$7F3D)にはRET命令、$FF3E(同オフセット$7F3E)にはSPの値が格納されている単純なイメージファイルだということです。
未使用の領域を利用して小さな転送プログラムを潜り込ませるという方法の為、この領域を利用するようなプログラムではこの手は使えません。またオートスタートするようなプログラムでもうまく転送出来ない場合があります。
N80を作成する時に調査した資料を元に編集しました。
ここで公開されている情報はあくまで私個人が調査した結果などであり、必ずしも正確とは限りません。