補足 MZ80のROM(SP1002)の情報です
***
補足 MZ80のROM(SP1002)の情報です。
***
読まないで次エピに進んで問題ないです。第二部を読んでいて、この番地は何だったかな? と思った時に参照して下さいな。
*
ROMルーチンとワークエリアについて簡単に説明します。...、調べていて判明した範囲でね。憶測で書いているところもあります。
ROMとは違いますが、E000h 番地以降のメモリマップドIOの情報も付けました。E000h を理解していないと何を処理しているか分からないコードがありましてね。
***
**
*
* * * * * * * * * * * * * * * *
* ROMルーチン(0000h〜0FFFh)
* * * * * * * * * * * * * * * *
0000-0002 : JP 004Ah ;Monitor
0003-0005 : JP 07E6h ;GETL
0006-0008 : JP 090Eh ;CR
0009-000B : JP 0918h ;CR2
000C-000E : JP 0920h ;SPACE
000F-0011 : JP 0926h ;TAB10
0012-0014 : JP 0935h ;PRNT
0015-0017 : JP 0981h ;MSG
0018-001A : JP 0999h ;MSG2
001B-001D : JP 08BDh ;GET KY
001E-0020 : JP 0A32h ;BR KEY
0021-0023 : JP 0436h ;save 1
0024-0026 : JP 0475h ;save 2
0027-0029 : JP 04D8h ;load 1
002A-002C : JP 04F8h ;load 2
002D-002F : JP 0588h ;verify
0030-0032 : JP 01C7h ;MELDY
0033-0035 : JP 0308h ;TIM ST
0036,____ : nop
0037,____ : nop
0038-003A : JP 1038h ;(interrupt)
003B-003D : JP 0358h ;TIM RD
003E-0040 : JP 02E5h ;BELL
0041-0043 : JP 02FAh ;XTEMP
0044-0046 : JP 02ABh ;MSTA
0047-0049 : JP 02BEh ;MSTOP
ROMの先頭はジャンプ命令が並んでいて、ROMルーチンの実際の処理はジャンプ先で行う。
Z80は電源オン時やリセット時に 0000h 番地から実行開始する。0000h 番地から 004Ah 番地にジャンプして初期化処理を行い、0082h 番地のメインループに行く。
初期化処理で IM 1 命令によりモード1を設定する。モード1は割り込み(INT)発生時に 0038h 番地へ行く。0038h 番地から 1038h 番地にジャンプするが、1038h 番地は初期化処理で jp 0392h と設定していて、0392h 番地にジャンプする。
INT → 0038h → 1038h → 0392h とたらい回し的な感じ?
0392h 番地のルーチンは 119Bh (AM/PM) 番地と時計を更新する。...、つまり電源オン後、12 時間後に割込みが発生してね、...。変なことをしているとここでバグる。かもね。
ノンマスカブル割り込み(NMI)はプルアップされていて発生しない。
*
004A-0081 : モニタの初期化処理; 初期化後 016Bh へジャンプ
初期化処理の内容
・スタックポインタを 10F0h に設定
・モード1に設定 (IM 1)
・0FC9h をコール
・0012h をコール(PRNT); A=16h
・0FD8h をコール; B=3Ch, HL=1170h
・1038h-103Ah に jp 0392h を設定
・[119Eh] = 04h
・[119Fh] = 05h
・02BEh をコール(MSTOP)
・0015h をコール; DE=0141h # = "** MONITOR SP-1002 **",0D
・016Bh へジャンプ (SSコマンドを実行, メインループへ)
*
0082-00CE : モニタのメインループ
コマンドは LOAD,GOTO,SS,SG,FD の5つ。
最初に "*" を表示して、0003h (GETL) をコールしてキー入力待ちをします。Break KEY と最初の "*" は無視です。
コマンドだったら各番地にジャンプ。コマンド以外なら "*" を表示してキー入力待ちです。
*
00CF-0130 : LOADコマンド
0131-0137 : データ; "FOUND ",0Dh
0138-0140 : データ; "LOADING ",0Dh
0141-0158 : データ; "** MONITOR SP-1002 **",0Dh
0159-016A : GOTOコマンド
016B-0172 : SSコマンド; [119Dh]=FFh; jp 0082h
0173-0176 : SGコマンド; [119Dh]=00h
0177-017F : FDコマンド
0180-0195 : 文字列の比較; [DE++]?=[HL++],B--
0196-0199 : データ; "LOAD"
019A-019D : データ; "GOTO"
019E-019F : データ; "SS"
01A0-01A1 : データ; "SG"
01A2-01A3 : データ; "FD"
01A4-01B4 : エラー表示してメインループに戻る
01B5-01C6 : データ; "CHECK SUM ERROR",0Dh
*
01C7-021B : MELDY
021C-0270 : (MELDYからコール)
0271-0288 : データ()
0289-02A0 : データ()
02A1-02AA : データ()
02AB-02BD : MSTA
02BE-02C7 : MSTOP
02C8-02E4 : (MELDYからコール)
02E5-02F9 : BELL
02FA-0307 : XTEMP
*
0308-0357 : TIM ST
0358-0391 : TIM RD
0392-03B9 : 割り込み発生時の処理; 119Bh(AM/PM)を更新, 時計に 12*3600-2 を加算
*
03BA-03C2 : HLを16進数4桁で表示(03C3hをコール)
03C3-03D9 : Aを16進数2桁で表示(0012hをコール)
03DA-03E8 : 00h-0Fhをアスキー("0"-"F")に変換してAにセット
03E9-03F8 : データ(30h-39h,41h-46h)
03F9-040F : Aのアスキー("0"-"F")を00h-0Fhに変換してAにセット
0410-041E : DEのアスキー列4バイトを16進数変換してHLにセット
041F-0435 : DEのアスキー列2バイトを16進数変換してAにセット
*
0436-046B : save 1
046C-0474 : データ; "WRITING ",0Dh
0475-048C : save 2
048D-04D7 : データの書込み(セーブ)
04D8-04F7 : load 1
04F8-050F : load 2
0510-0587 : データの読込み(ロード)
0588-05B1 : verify
05B2-0600 : データをロードしてメモリと比較
0601-0623 : 0⇒1の変化を検出
0624-065D : 8ビット分をAレジスタにセット
065E-06B1 : ヘッダ検出([1]*40と[0]*40と1)
06B2-06FF : カセットのスタート検出
0700-0721 : 終了処理(カセット停止)
0722-0728 : データ; 7Fh," PLAY",0Dh
0729-0732 : データ; 7Fh," RECORD.",0Dh
0733-0758 : メモリからチェックサムを計算
0759-075F : 時間待ち(0Eh回ループ)
0760-0766 : 時間待ち(0Dh回ループ)
0767-077F : 「0」を書込み
0780-07A4 : 「1」を書込み
07A5-07B7 : 1バイトを書込み
07B8-07E5 : ピー音の書込み
*
07E6-08BC : GET L; 1行入力; 09B3hをコール
08BD-08C9 : GET KY; 1文字入力
08CA-090D : GET KY の本体; 0A50hをコール,0AC9hを参照,シフトとカナの処理
090E-0917 : CR
0918-091F : CR2
0920-0925 : SPACE
0926-0934 : TAB10
0935-0945 : PRNT
0946-0980 : 文字表示用ルーチン(PRNT,MSGからコール)
0981-0998 : MSG
0999-09B2 : MSG2
09B3-09FE : キー入力; 入力をAにセットしてリターン
09FF-0A31 : カーソル点滅
0A32-0A43 : BR KEY
0A44-0A4F : BR KEY 2
0A50-0AC8 : キーマトリクスをスキャン; Bに入力の有無, Cにロウとカラム
0AC9-0BB8 : データ(ロウとカラムをディスプレイコードに)
*
0BB9-0BCE : アスキーをディスプレイコードに変換
0BCE-0BD5 : ディスプレイコードをアスキーに変換
0BD6-0CC5 : データ(アスキーコード 10h-FFh をディスプレイコードに)
0CC6-0DA5 : データ(ディスプレイコード 00h-DFh をアスキーコードに)
*
0DA6-0DB4 : 垂直BLANK検出 (ブランクになったらリターン)
0DB5-0DDB : ディスプレイコードをカーソル位置に表示
0DDC-0DF2 : カーソル制御; Aの値で分岐(A=C0h〜CFh)
0DF3-0E31 : 分岐先(16個のJP命令)
0E32, 0E74, 0E84, 0E90, 0EAE, 0EBF, 0EC5, 0EF8,
0F49, 0EE1, 0EEE,*0FDE,*0FDE, 0F8B,*0FDE,*0FDE
# CBh,CCh,CEh,CFhは処理なし
0E32-0E73 : C0 スクロールアップ
0E74-0E83 : C1 [↓]
0E84-0E8F : C2 [↑]
0E90-0EAD : C3 [→]
0EAE-0EBE : C4 [←]
0EBF-0EC4 : C5 [H]
0EC5-0EE0 : C6 [C]
0EE1-0EF7 : C9 [英数]
0EEE-0EF7 : CA [カナ]
0EF8-0F48 : C7 [DEL]
0F49-0F87 : C8 [INS]
0F8B-0FB0 : CD [CR]
0FB1,____ : ld HL,(1171h) #次に続く
0FB4-0FC8 : H=Y座標,L=X座標を番地に変換してHLにセット
*
0FC9-0FD7 : 初期化; 8255モード設定, モータ切替, LED緑色, 画面オン
0FD8,____ : xor A
0FD9-0FDD : ld (HL),A; inc HL; djnz 0FD9h; ret
0FDE,____ : pop HL
0FDF-0FE2 : pop DE; pop BC; pop AF; ret
0FE3-0FFF : データ()
AE CD EE FF
AE FE AC DE
4E FF
AE DF
AE DF 2F FF
26
7D FE FD EE FD AC
DF
7E DF
7E DF
AE DF FF
* * * * * * * * * * * * * * * *
* ROMルーチンのワークエリア(1000h〜11FFh)
* * * * * * * * * * * * * * * *
1000-1037: 未使用?
1038,103A: 割込み時のジャンプ命令; 3C 0392h = jp 0392h
103B-10EF: モニター用スタック領域
*
10F0-116F: SAVE, LOAD のバッファ; 128バイト
・10F0,____ 種別; 01h=BIN,02h=BAS,03h=SEQ
・10F1-1100 ファイル名(最大16文字)
・1101,____ 終端 0Dh
・1102,1103 バイト数;
・1104,1105 ロード先; BASは無視,4806hに固定
・1106,1107 実行番地; 1200h以上ならジャンプ; BASは無視
・1108,____ フラグ; BASの場合,00h以外ならLIST,SAVE禁止
・1109,____ フラグ; BASの場合,00h以外ならオートRUN
・110A-116F 未使用?
*
1170,____: カナ/英数; 00h=英数, 01h=カナ
1171,____: カーソル位置X (0〜39); 原点は左上, Xは横→, Yは縦↓
1172,____: カーソル位置Y (0〜24)
1173-118D: 00h=前行と未接続,01h=接続中; 26行分, 118Dhは00h固定で番兵くんか
118E,____: カーソル位置のディスプレイコード(カーソル点滅用)
118F,1190: カーソル位置の番地(カーソル点滅用)
1191,____: カーソル点滅のワーク用 (09FFhのルーチンで使用)
1192,____: カーソルのディスプレイコード;EFh
1193,____: エコーバック時のカーソル制御のオンオフ
1194,____: カーソル位置X; 0〜79の2行分
*
1195,1196: LOAD時のワーク用; 連続する1の個数の初期値を保持
1197,1198: LOAD時のワーク用; データの1の個数をカウント
1199,119A: メモリから計算したチェックサム; VERIFYでLOADした値と比較
*
119B,____: AM/PM; 00=AM, 01=PM
119C,____: TIMSTでF0hに設定, LOAD,SAVEで参照(終了時にF0hならEIする)
*
119D,____: キー入力時の音のオンオフ; SGで00h,SSでFFh
119E,____: テンポ; 04h; (XTEMPで設定)
119F,____: 音の長さ; 05h;
11A0,____: オクターブ; 01h,02h,03h;
11A1,11A2: 周波数; (MELDYで設定, MSTAで参照してE004hに転送)
*
11A3-11F2: キー入力バッファ; GETL(0003h) 用, 80文字分?
11F3,11FF: 未使用?
* * * * * * * * * * * * * * * *
* メモリマップドI/O
* * * * * * * * * * * * * * * *
E000-E003:8255(周辺IF)
[E003h] = 8Ah で使用
・ポートA = E000h 出力
・ポートB = E001h 入力
・ポートC = E002h 上位4ビットは入力、下位4ビットは出力
※ ポートCの出力は E003h のシングルビット操作で処理
E000:ポートA; キー・スキャン
D7 W:カーソル点滅用タイマーのリセット
D6-D4 W:(未接続?)
D3-D0 W:キーボードスキャンのロウ出力 (0-9を指定)
E001:ポートB; キー・スキャン
D7-D0 R:キーボードスキャンのカラム入力
ロウ出力(0-9)で選択されたキーのうち、押下されたキーがあれば対応するビット(D7-D0)が 0 になる。キー押下がなければ FFh になる。
E002:ポートC; 画面・カセットテープ・LED
D7 R:VBLANK
D6 R:カーソル点滅用タイマーのステータスビット
D5 R:カセットからの読取りデータ
D4 R:カセットの状態の検出 0=停止 1=回転中
D3 W:カセットの制御 (回転/停止) 0→1で切替
D2 W:英数・カナのLED 0=赤色 (カナ) 1=緑色 (英数)
D1 W:カセットへの書込みデータ
D0 W:VGATE 0=画面オフ 1=画面オン
E003:8255のモード設定・ポートCのビットON/OFF
ポートCの D3-D0 のシングルビット操作は、D3-D1 でビットを選択して、D0 で 0/1 を指定する。
011x:06h→ 07hでカセットの回転/停止を切替
010x:04h=赤色 05h=緑色 ;LED
001x:02h=0 03h=1 ;カセットへの書込み
000x:00h=オフ 01h=オン ;画面出力
E004-E008:8253(インターバル・タイマー)
音楽で利用してるよ
***
間違いの指摘とか疑問とか、ご意見・ご感想とかありましたら、どうぞ感想欄に!
***
2026.4.18 エピを入れ換え(初出: 2026/03/08 02:03)




