Loading [MathJax]/extensions/tex2jax.js

2020年9月30日水曜日

Z8530 SCC

 Z8530 SCCを制御するコードも上げておきます。

先ずは初期化のコードです。送受信の割り込みが処理できるように初期化しています。この石もかなり曲者で初期化手順を間違うとうまく動きません。

発生させる割り込み込みベクタは0x10からで、チャンネルAの送信が0x18で、受信が0x1cになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    .equ    SCCAC, 0x0009
    .equ    SCCAD, 0x000D
 
init_scc:
    ld  r2, #(scccmde - scccmds)    ! initialize Z8530
    ld  r3, #SCCAC
    ld  r4, #scccmds
    otirb   @r3, @r4, r2
    ret
 
scccmds:
    .byte   9, 0xc0     ! Reset
    .byte   4, 0x44     ! x16, 1stop-bit, non-parity
    .byte   3, 0xe0     ! Receive  8bit/char, rts auto        
    .byte   5, 0xe2     ! Send 8bit/char, dtr rts
 
    .byte   2, 0x10     ! Interrupt vector
    .byte   1, 0x12     ! Interruprt on Rx All character and Tx Int
    .byte   9, 0x09     ! MIE, VIS, Status=Low
 
    .byte   11, 0x50    ! BG use for receiver and transmiter
    .byte   12, 30      ! 4800bps at 5MHz clock
    .byte   13, 00
    .byte   14, 0x02    ! PCLK for BG
    .byte   14, 0x03    ! BG enable
 
    .byte   3, 0xe1     ! Receiver enable
    .byte   5, 0xea     ! Transmiter enable
 
scccmde:

割り込みハンドラーは、次のようなコードです。リングバッファ処理部分は端折ってあります。Z8536と同じで割り込み処理の終了処理を正しく行わないと、優先順位の低い割り込みがかからなくなったりします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
scc_rxint:              ! Rx InterruptHandler
    push    @r15, r0
    push    @r15, r1
1: 
    inb rl0, #SCCAC
    andb    rl0, #0x01
    jr  z, 1b
    inb rh0, #SCCAD     ! Read a data from Rx buffer
     
    !
    !
     
    ldb rl0, #0x38      ! Enable IUS
    outb    #SCCAC, rl0
    pop r1, @r15
    pop r0, @r15
    iret
 
scc_txint:              ! Tx Interrupt Handler
    push    @r15, r0
    push    @r15, r1
 
    !
    !
     
    outb    #SCCAD, rl0 ! Write a data to Tx buffer
     
    ldb rl0, #0x28      ! Clear Tx interrupt pendinng
    outb    #SCCAC, rl0
    ldb rl0, #0x38      ! Enable IUS
    outb    #SCCAC, rl0
     
    pop r1, @r15
    pop r0, @r15
    iret

2020年9月12日土曜日

Z8536 CIO

 Z8536の初期化手順と割込み処理のメモです。カウンタタイマ3で10mS周期の割り込みをかけます。

Z8536にはRESETピンがなく、ハードウェアリセットはRDピンとWRピンを同時にLにすることで行います。今回はハードウェアを手抜きしているので、ソフトウェアでリセットしています。A0, A1ピンをHにしてリードし、つづいて、レジスタ0に1を書き込んだのちレジスタ0に0を書き込みます。これで初期化されます。

レジスタのアクセスは、A0, A1ピンをHにしアクセスするレジスタ番号を書き込み、つづいて目的のレジスタに書き込みか読み込みをします。Z8536を初期化するのにレジスタ設定の順番を変えたりすると、なぜか動かなくなったりします。正しい手順はよく理解できていないのですが、手探りで見つけた手順が下のコードです。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    .equ    CIOPRTC, 0x0011
    .equ    CIOPRTB, 0x0015
    .equ    CIOPRTA, 0x0019
    .equ    CIOCTRL, 0x001d
 
 
init_cio:
    ld  r1, #CIOCTRL
    inb rl0, #CIOCTRL
    lda r2, ciocmds
    ld  r3, #(ciocmde - ciocmds)
    otirb   @r1, @r2, r3
    ret
 
ciointr:
    push    @r15, r0    ! レジスタ保存
    push    @r15, r1
 
    ! 割り込み処理
    !
    !
     
    ldb rl0, #0x0c
    outb    #CIOCTRL, rl0
    ldb rl0, #0x24
    outb    #CIOCTRL, rl0   ! Clear IP and IUS
     
    pop r1, @r15    ! レジスタ復帰
    pop r0, @r15
    iret
 
!------------------------------------------------------------------------------
 
ciocmds:
    .byte   0x00, 0x01      ! Reset
    .byte   0x00, 0x00      ! Clear reset
    .byte   0x01, 0x00      ! Reset PortC and C/T3
    .byte   0x01, 0x10      ! Enable PortC and C/T3
    .byte   0x1e, 0xc2      ! Continuous, Ext Output, Square wave
    .byte   0x1a, 0x30      ! Set timer constant
    .byte   0x1b, 0xd4      ! Set timer constant
    .byte   0x00, 0x84      ! MIE and VIS
    .byte   0x04, 0x00      ! Set Interupt vector
    .byte   0x0c, 0xc0      ! Set Interupt Enable bit
    .byte   0x0c, 0x06      ! Gate and Triger
ciocmde:


割り込み処理は、最後にレジスタ12のIPとIUSをクリアして戻れば、続けて割り込みが発生します。これを忘れると、割り込みが単発になったり、他のチップからの割り込みが発生しなくなります。

Z8530もそうでしたが、Zilogの周辺チップはプログラムが難しい印象です。さらにデータシートが不親切で、読んだだけでは理解できないことが多々あります。ネット上にもあまり情報がないので、手探りがで動かすことになるのですが、動いた時の高揚感は格別です。

2020年9月6日日曜日

Z8002にMMUを その3

今回作成したMMUの回路図が下です。

高速SRAM, マルチプレクサ、双方向バッファ、CPLDからなっており、CPLDが各ICの制御信号を作っています。TTL-ICを組み合わせて制御信号を作るのは面倒なのと、うまく動かなかったときに、CPLDだと回路の変更をせずにロジックを書き換えるだけで対処できます。

CPLDの定義ファイルのMMUに関連する部分の抜粋です。
1
2
3
4
5
6
7
8
IOREQ = ST0 # !ST1 # ST2 # ST3;
 
DI = !ST3;
MMUSEL = !A15 # !A14 # IOREQ;
MAPSEL = MMUENA & MMUSEL;
MMUBUFE = MMUSEL # DS;
MAPRD = (MMUSEL # !RW # DS) & !IOREQ;
MAPWR = MMUSEL # RW # DS;
1個のCPLDでメモリアクセス用の信号も作ったりしているので、I/Oをほぼ使い切ってしまっています。
アドレスマップの高速SRAMは、I/O空間でアクセスでき読み書きができます。アドレスは次のようになっています。

- no title specified

I/O Addr

N/S

D/I

Page No.

C001

S

I

0

:

:

:

:

C01F

S

I

F

C021

N

I

0

:

:

:

:

C03F

N

I

F

C041

S

D

0

:

:

:

:

C05F

S

D

F

C061

N

D

0

:

:

:

:

C07F

N

D

F

    
    
S --- System, N --- Normal (User), D --- Data, I --- Instruction

システムがリセットした時には、アドレスマップを初期化したのちMO端子をアクティブにすることでMMUが機能します。それまでCPUは、RAMの先頭ページ(4kバイト)しかアクセスできません。