ユーザ用ツール

サイト用ツール


mz-700

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
mz-700 [2023/12/06 19:16] – [MZ-800をMZ-700のようになるまで初期化する] arakimz-700 [2023/12/07 16:07] (現在) – [概要] araki
行 2: 行 2:
  
 ===== 概要 ===== ===== 概要 =====
 +
 +{{:undefined:mz721.jpg?400|}}
 ===== MZ-800エミュレータでMZ-700のIPLを使う ===== ===== MZ-800エミュレータでMZ-700のIPLを使う =====
  
行 33: 行 35:
 変換後のファイルを cgrom.romとする。 変換後のファイルを cgrom.romとする。
  
 +<code>
 +#!/usr/bin/env ruby
 +
 +cgrom_rev = []
 +open('font.rom') do |f|
 +  cgrom = f.read.unpack("C*")
 +  cgrom.each do |c|
 +    i = 128
 +    j = 1
 +    d = 0
 +    while i > 0 do
 +      d |= j if c & i != 0
 +      j <<= 1
 +      i >>= 1
 +    end
 +    cgrom_rev.push(d)
 +  end
 +end
 +open('cgrom.rom','w')do |f|
 +  f.write cgrom_rev.pack("C*")
 +end
 +</code>
 +
 +ファイルが揃ったら、MZ-800エミュレータのメニューからROM→Settings for User Defined...を選んで、Enable User Defined ROMにチェックを入れたら、Seperate ROM Binary Filesを選び、それぞれのROMファイルを指定する。
 +
 +{{::mz800emu_user_defined_rom.png?400|}}
 +{{::mz800emu_rom_setting.png?400|}}
 +
 +Applyを押せば、1Z-009Aが起動する。
 +
 +{{::mz800emu_1z-009a.png?400|}}
 +
 +==== MZ-800の初期化処理について ====
 +
 +MZ-800は電源投入後、またはリセット直後は MZ-800モードで起動するが、その後、MZ-700モードに移行し、CGROMや周辺デバイスの設定を行った後、ディップスイッチの設定を読んで、MZ-800またはMZ-700それぞれのモードに移行する。
 +
 +MZ-700のROMを使うのであればディップスイッチの如何に関わらずMZ-700モードへと移行し、本来のモニターに制御を戻すようにしてやればいい。
 +
 +この時、MZ-700とは異なるMZ-800のハードウェアを適切に設定して、適切なポイントへ制御を戻す必要がある。
 +
 +具体的に問題となる、MZ-700とMZ-800との違いには以下のものがある。
 +
 +  * MZ-800モードとMZ-700モード
 +  * CGROMデータのPCGへの転送処理
 +  * 画面モードの設定と画面クリア
 +  * 8255/8253およびSN76489ANの初期化
 +
 +=== MZ-800モードとMZ-700モード ===
 +
 +MZ-800はポート0xceに0x08を出力することで、MZ-700モードへと移行する。
 +このポートはディスプレーモードレジスタにつながっていて、画面モードの設定を行うのだが、0x08を渡すと、メモリーマップがMZ-700相当のものになる。
 +
 +この時、0x0000~0x0fffと0xe000~0xffffにはROM(0xe000~0x00fはmemory mapped I/O)が割り当てられ、0xd000~0xdfffにはVRAMが割り当てられる。
 +
 +IPL2.ROMではまずこの処理を行う。
 +
 +=== CGROMデータのPCGへの転送処理 ===
 +
 +MZ-800はMZ-700とは異なり、CG-ROMにCPUからアクセスができる。
 +また表示に使われるデータはPCGのデータが参照されるため、CG-ROMの内容をPCGに設定する必要がある。
 +
 +MZ-700モードにあるときに、ポート0xe0から値を読むと、0x1000~0x1fffにCG-ROMが、0xc000~0xcfffにPCGがそれぞれ割り当てられるので、この状態で、CG-ROMの内容をPCGに転送する。
 +
 +転送が終わったら、ポート0xe1から値を読みだせば再び0x1000~0x1fff, 0xc000~0xcfffにDRAMが割り当てられた状態に戻る。
 +
 +<code>
 +in a,(0e0h)
 +
 +ld hl,01000h
 +ld de,0c000h
 +ld bc,01000h
 +ldir
 +
 +in a,(0e1h)
 +</code>
 +
 +これで、MZ-700のCG-ROMデータ((ここでは、エミュレータ用のデータだが。))が表示に使用されるようになった。
 +
 +=== 画面モードの設定と画面クリア ===
 +
 +MZ-700のROM内にも画面クリアーのコードがあるが、アトリビュートだけを0x71(文字色白、背景青)にするだけで、文字データ自体をクリアしない。
 +
 +MZ-700の場合はリセットでおそらくテキストVRAMがクリアされるのだが、MZ-800ではそうではないため、VRAMをクリアするコードを追加してやる必要がある。
 +これを行わないとリセット直後に謎の模様が画面に表示されることになる。
 +
 +
 +=== 8255/8253およびSN76489ANの初期化 ===
 +
 +MZ-700と異なり、MZ-800は8253のポート0の出力がスピーカーに直結せずに、代わりに SN76489ANの Audio INにつながっている。
 +また、SN76489ANにクロックの供給も行っている。
 +このクロックの供給の制御は 8255が行っている。
 +
 +このため、この関係に従って初期化を行わないと、謎のホワイトノイズが出っぱなしになり、8253にコマンドを送っても音を奏でることがなくなってしまう。
 +
 +MZ-700の8255の初期化は、8253からSN76489ANへのクロック供給を有効化しないため、これに代わる処理を行い、逆にMZ-700側の初期化ルーチンをバイパスしてやる必要がある。
 +
 +幸い、1Z-009Aの8253/8255の初期化はほぼ初めに行われるため、モニターのエントリーポイントではなく、この処理の直後に、IPL2.ROM側から戻してやることで、システムの状態を正しく保ったまま処理を継続させることができる。
 +
 +==== 初期化コード ====
 +
 +上記の処理を以下のように実装した。
 +
 +<code>
 +;===========================
 +; MZ-800 to MZ-700
 +;===========================
 +        .z80
 +        org     0e800h
 +mz700   equ     00052h  ; do not return to 004ah
 +stack   equ     010f0h
 +cgrom   equ     01000h
 +pcgram  equ     0c000h
 +mset53  equ     00308h
 +
 +entry:
 +        di
 +        im      1               ; set interrupt mode to 1
 +
 +        ld      a,8             ; set MZ-700 mode
 +        out     (0ceh),a
 +        ld      a,1             ; set CRTC to MZ-700 mode
 +        out     (0cdh),a
 +        out     (0cch),a
 +        out     (0e4h),       ; set memory map
 +        ld      sp,stack        ; initialize stack pointer
 +        ; init 8255
 +        ld      a,08ah
 +        ld      (0e003h),     ; set 8255 to MZ-700/800/1500 mode
 +        ld      a,1
 +        ld      (0e003h),     ; enable clock supply to SN76489AN
 +        ld      a,5
 +        ld      (0e003h),     ; enable timer interrupt
 +        ; init 8253
 +        ld      de,0
 +        call    mset53
 +        ; init PIO
 +        ld      bc,04fch
 +        ld      hl,piodat
 +        otir
 +        ld      bc,04fdh
 +        otir
 +        ; init SIO
 +        ld      a,1
 +        out     (0f7h),a
 +        xor     a
 +        out     (0f7h),a
 +        ; init PSG (SN76489AN)
 +        ld      b,4
 +        ld      a,09fh
 +psgset:
 +        out     (0f2h),a
 +        add     a,020h
 +        djnz    psgset
 +        ; init screen
 +        ld      hl,0d800h
 +        ld      de,0d000h
 +        ld      bc,0400h
 +cls_loop:
 +        ld      (hl),71h        ; set fgc=7/bgc=1
 +        inc     hl
 +        xor     a
 +        ld      (de),         ; erase vram
 +        inc     de
 +
 +        dec     bc
 +        ld      a,b
 +        or      c
 +        jr      nz,cls_loop
 +
 +        ; copy CGROM to PCG
 +        in      a,(0e0h)
 +        ld      de,pcgram
 +        ld      hl,cgrom
 +        ld      bc,1000h
 +        ldir
 +        in      a,(0e1h)
 +
 +        jp      mz700
  
 +        org     0e900h
 +piodat  db      000h,0cfh,03fh,007h,000h,0cfh,000h,007h
  
 +        end
 +</code>
  
mz-700.1701857811.txt.gz · 最終更新: 2023/12/06 19:16 by araki