Super AKI-80 を使ってみる(3)
Super AKI-80 で BASIC を動かす
I/O エミュレーション
CH32V203 との接続では A0-A7 までしかつながっていないので、現時点では 256 バイトのプログラムしか書き込むことができませんでした。 ここでは、それ以上のプログラムを Z80 側に転送できるようにします。
DMA の処理が終了したのちの CH32V203 を Z80 の I/O デバイスとして振舞うようにして、続きのコードを読めるようにします。 ここでは仮に Z80 の IO ポート番号 $40 でやり取りできるようにします。
CH32V203 側の処理は単純で、Z80 バスを監視して IO アクセスが来たら反応するようにします。 Z80 では IO アクセスには自動的に 1Wait 挿入されるので、10MHz 動作時に 3 clocks = 300nsec の余裕があります。
しかし、CH32V203 の GPIO 入力には 144MHz 時でも 70ns ほどかかるので、 そのままでは対応できません。
そこで IO アクセスの際には自動で WAIT 状態になるようにして、明示的に WAIT を解除するようにします。 (参考文献) なお、Super AKI-80 の WAIT のプルアップ抵抗は外してあります。
内蔵ペリフェラルへのアクセスでも反応してしまうので、CH32V203 へのアクセスでないときにも WAIT を解除する処理が入っています。 また、モード2 割り込みの際にも反応してしまうので、これにも対応する必要があります。
前回と比べて以下の信号線が追加で配線されています。
- WAIT 1K の抵抗を介して IORQ とも接続されています。 
- M1 
BASIC を動かす
電脳伝説さんの移植した MBASIC を動かします。
起動するときに DMA で、ブートローダを SRAM に書き込みます。
        org 0
BOOTLOAD equ $4000              ; Bootloader store area
PORT    equ $40                 ; I/O port for load code from CH32V203
        ;; move boot loader to another area
start:
        di
        ld sp,$8000
        ld hl,$0
        ld de,BOOTLOAD
        ld bc,$100
        ldir
        jp BOOTLOAD+blstart
        ;; bootloader code
blstart:
        ;; send I/O to reload trigger
        ld a,$00
        out (PORT),a
        ;; get code size
        in a,(PORT)
        ld c,a
        in a,(PORT)
        ld b,a
        ;;
        ld hl,0
loop:
        in a,(PORT)
        ld (hl),a
        inc hl
        dec bc
        ld a,b
        or c
        jr nz,loop
        ;;
        jp 0
書き込まれたブートローダは BASIC と配置が被るので、一旦じゃまにならない位置に転送します。
次に CH32V203 の IO エミュレーションを使って、BASIC のコードを転送して BASIC の先頭にジャンプします。

BASIC 側には特に変更なくバイナリをそのまま使用しました。
おわりに
CH32V203 を使って、完全オール RAM の Z80 システムを作成することができました。 IO アクセスのエミュレーションができるようになったので、 SPI フラッシュや SD カードを使った外部記憶装置のエミュレーションにもチャレンジしてみたいと思います。