目次
前
次
WonderKit_Z80_board2
部屋を掃除していると、TMPZ84C011を利用したWonderKit
の基板が出てきました。
TMPZ84C011は、I/OにCTCと独自仕様のパラレルポートを
内蔵したZ80シリーズですが、シリアルポートを持たない
ので、使いやすくなっています。
シリアルインタフェースを持たないと不便ですが
データ交換をSPI準拠にすると、Arm、Arduino利用
で、データ交換できます。Arm、Arduinoはシリアル
処理とSPI処理を担当させます。
パラレルポートは、AからEの5チャネルあり
入出力指定とポートの2種のレジスタで制御
できます。
I/Oアドレスは、以下となっています。
入出力指定
アドレスは、以下。
PACON EQU 54h
PBCON EQU 55h
PCCON EQU 56h
PDCON EQU 34h
PECON EQU 44h
レジスタの該当ビットに1をライトすると出力
0をライトすると入力になります。
ポートのビット毎に入出力を指定できるので
Z80PIOより使いやすいですが、割込みに対応
していないので、入力変化はタイマー割込み
で検出すればよいでしょう。
ポート
アドレスは、以下。
PADAT EQU 50h
PBDAT EQU 51h
PCDAT EQU 53h
PDDAT EQU 30h
PEDAT EQU 40h
基板の配線を追って、ROMとRAMの配置がどうなっている
のか調べるのが面倒なのでファームウエアを8kバイト
のROMに焼いてプログラムで調べることにしました。
SRAMとして8kバイトが載せられているので
64kバイトを8分割すると、SRAMの先頭は
2000h、4000h、6000h、8000h、A000h、C000h
のどれかです。スタックポインタを、SRAMの
最終アドレスしておいて、ファームウエアが
動けばビンゴになります。
SRAMの先頭アドレスとスタックの関係は、以下。
entry stack
2000h 4000h
4000h 6000h
6000h 8000h
8000h A000h
A000h C000h
C000h 0000h
組み合わせは、6種類だけなのでプログラムで
スタックは、次のように記述してコメント記号
の追加、削除で対応できます。
SENT EQU 2000h
;SENT EQU 4000h
;SENT EQU 6000h
;SENT EQU 8000h
;SENT EQU 0A000h
;SENT EQU 0C000h
STKT EQU SENT+2000h
;STKT EQU 0h
スタックポインタの設定は、以下のようにします。
;SENT EQU 2000h
;SENT EQU 4000h
;SENT EQU 6000h
SENT EQU 8000h
;SENT EQU 0A000h
;SENT EQU 0C000h
STKT EQU SENT+2000h
;STKT EQU 0h
org 0h
jp start
org 100h
start:
ld sp,STKT
call INIT_PIO
call INIT_other
main:
call PIO_PROC
call CNT_OUT
jp main
パラレルポートの入出力を指定するサブルーチンを
定義します。ポートB、Cを出力に、他を入力に設定
すると、以下。
INIT_PIO:
push af
push bc
;
ld a,PAINIT
ld c,PACON
out (c),a
;
ld a,PBINIT
ld c,PBCON
out (c),a
;
ld a,PCINIT
ld c,PCCON
out (c),a
;
ld a,PDINIT
ld c,PDCON
out (c),a
;
ld a,PEINIT
ld c,PECON
out (c),a
;
pop bc
pop af
ret
ポートCからは、0から255の値を出力します。
CNT_OUT:
push af
push bc
; set PORT number
ld c,PCDAT
; get counter
ld a,l
; inverse
cpl
; output
out (c),a
; counter increment
inc hl
;
pop bc
pop af
ret
ポートCへの出力は、カウンタを用意して初期化
しておきます。HLレジスタペアを、カウンタに
使います。
INIT_other:
push af
push bc
;
xor a
ld h,a
ld l,a
;
pop bc
pop af
ret
ポートAの入力値を反転し、ポートBへ出力する
処理で、2ポートのテストをします。
PIO_PROC:
push af
push bc
;
ld c,PADAT
ld b,PBDAT
; get data
in a,(c)
cpl
; put data
ld c,b
out (c),a
;
pop bc
pop af
ret
まとめます。
SENT EQU 8000h
;SENT EQU 4000h
;SENT EQU 6000h
;SENT EQU 8000h
;SENT EQU 0A000h
;SENT EQU 0C000h
STKT EQU SENT+2000h
PACON EQU 54h
PBCON EQU 55h
PCCON EQU 56h
PDCON EQU 34h
PECON EQU 44h
PADAT EQU 50h
PBDAT EQU 51h
PCDAT EQU 53h
PDDAT EQU 30h
PEDAT EQU 40h
PAINIT EQU 00h ; inputs
PBINIT EQU 0ffh ; outputs
PCINIT EQU 0ffh ; outputs
PDINIT EQU 00h ; inputs
PEINIT EQU 00h ; inputs
org 0h
jp start
org 100h
start:
ld sp,STKT
call INIT_PIO
call INIT_other
main:
call PIO_PROC
call CNT_OUT
call SWAIT
jp main
;*****************************
INIT_PIO:
push af
push bc
;
ld a,PAINIT
ld c,PACON
out (c),a
;
ld a,PBINIT
ld c,PBCON
out (c),a
;
ld a,PCINIT
ld c,PCCON
out (c),a
;
ld a,PDINIT
ld c,PDCON
out (c),a
;
ld a,PEINIT
ld c,PECON
out (c),a
;
pop bc
pop af
ret
INIT_other:
push af
push bc
;
xor a
ld h,a
ld l,a
;
pop bc
pop af
ret
PIO_PROC:
push af
push bc
;
ld c,PADAT
ld b,PBDAT
; get data
in a,(c)
cpl
; put data
ld c,b
out (c),a
;
pop bc
pop af
ret
CNT_OUT:
push af
push bc
; set PORT number
ld c,PCDAT
; get counter
ld a,l
; inverse
cpl
; output
out (c),a
; counter increment
inc hl
;
pop bc
pop af
ret
SWAIT:
push af
push bc
;
ld c,255
SWAITL:
; set counter
ld b,255
SWAITLP:
nop
; b <= b - 1
djnz SWAITLP
;
dec c
ld a,c
;
cp 0
jr nz,SWAITL
;
pop bc
pop af
ret
end
基本となる調査用プログラムを作成したなら
I/Oのピンアサインを導通チェッカーで調べ
ました。
50ピンのコネクタのピンアサインは、以下。
1 GND 2 CLK/TRG3
3 CLK/TRG2 4 CLK/TRG1
5 CLK/TRG0 6 ZC/TO0
7 ZC/TO1 8 ZC/TO2
9 PD0 10 PD1
11 PD2 12 PD3
13 PD4 14 PD5
15 PD6 16 PD7
17 PE0 18 PE1
19 PE2 20 PE3
21 PE4 22 PE5
23 PE6 24 PE7
25 PB0 26 PB1
27 PB2 28 PB3
29 PB4 30 PB5
31 PB6 32 PB7
33 PA0 34 PA1
35 PA2 36 PA3
37 PA4 38 PA5
39 PA6 40 PA7
41 PC0 42 PC1
43 PC2 44 PC3
45 PC4 46 PC5
47 PC6 48 PC7
49 Vcc 50 GND
コネクタには、CTCとPIOの信号線が接続されています。
この信号線配置は、チップの信号ピンの並びで決められ
ているようです。
10ピンケーブルワイヤーを使えば、PIOCを利用する
プログラムのテストができます。
電源ピンは、次のようになっていました。
1 Vcc
2 <74HC14 1pin>
3 GND
4 Vcc
5 GND
電源は5ピンですが、2ピンはシュミットインバータ
74HC14の1ピンに接続されています。同時に、正電圧
に抵抗を介して接続されています。
2ピンをVccに接続すると、基板上にあるアドレスデコーダが
イネーブルになります。GNDに接続するとアドレスでコーダを
ディセーブルにするため、基板上のメモリを使うか、外付け
のメモリを利用するかを指定できます。
外部にメモリを接続することを考えているのか
30ピンコネクタがあります。
導通チェッカーで確認できた信号は、以下です。
1 GND 2 GND
3 Vcc 4 nRESET
5 nIORQ 6 nMREQ
7 nWR 8 nRD
9 A7 10 A6
11 A5 12 A4
13 A3 14 A2
15 A1 16 A0
17 D7 18 D6
19 D5 20 D4
21 D3 22 D2
23 D1 24 D0
25 nINT 26 E1
27 nBUSREQ 28
29 30 nRFSH
リフレッシュ信号があり、アドレスが8ピンしか
出ていないので、外部にはDRAMを接続することを
考えていたのかも知れません。
タイマー、PIO以外のI/Oであるシリアルインタフェース
を拡張することを考えたピンアサインの様に見えます。
後で、26ピンのフラットケーブルを利用し、CTC、PIOでは
ないI/Oを、拡張基板に半田付けしてみます。
I/O部分がわかったので、64kバイトのメモリ空間をどう
扱っているのか、アドレスデコーダを回路図にしました。
アドレスデコーダから、メモリは0hからROM、8000hからRAM
が配置されていることがわかります。
8kバイトのSRAMが実装されていたので、スタックポインタは
次のように設定すればよいと理解できます。
SENT EQU 8000h
STKT EQU SENT+2000h
org 0h
jp start
org 100h
start:
ld sp,STKT
メモリ配置がわかったので、CTCのテストをします。
CTCは、ZC/TO0、ZC/TO1、ZC/TO2の3出力に異なる
周波数のクロックを出力してチェックします。
CPUが利用しているクロックが4MHzなので、分周して
次のクロックを出力します。
ZC/TO0 prescaler:1/16 time constant:256 (976Hz)
ZC/TO1 prescaler:1/256 time constant:128 (122Hz)
ZC/TO2 prescaler:1/256 time constant:256 (61Hz)
CTCはカウンタモード、タイマーモードが選べますが
タイマーモードを利用します。
CTCの制御レジスタには、次の項目を指定します。
- 割込み 0:割込みなし 1:割込みあり
- モード 0:タイマーモード 1:カウンターモード
- プリスケーラ 0:1/16 1:1/256
- パルスエッジ 0:falling 1:rising
- 起動指示 0:自動 1:トリガーパルス (タイマーモードでのみ有効)
- 定数 0:時間定数書込みなし 1:時間定数書込みあり
- リセット 0:時間定数書込み無視 1:時間定数書込みまで待機
- 制御ワード 1:チャネル制御語指定
CTCの各チャネルの初期化は、割込みを利用しないときには
次の手順になっています。
制御ワードライト
時間定数ライト
この動作をチャネル回数だけ繰り返せばよいので、制御ワードと
時間定数を定義して、OUT命令で書き出します。
CTCのI/Oアドレスは、Z84C015と同じなので、次のように定義。
CTC_C0 EQU 10H
CTC_C1 EQU 11H
CTC_C2 EQU 12H
CTC_C3 EQU 13H
チャネル0から2までの制御ワードと時間定数を定義します。
C0INI EQU 15H ; 00010101
C0TCNT EQU 00H ; 00000000(256)
C1INI EQU 35H ; 00110101
C1TCNT EQU 80H ; 10000000(128)
C2INI EQU 35H ; 00110101
C2TCNT EQU 00H ; 00000000(256)
初期化したなら自動でタイマーが動くので、ダイナミック
ストップで動作を確認できるようにします。
SENT EQU 8000h
STKT EQU SENT+2000h
; CTC I/O address
CTC_C0 EQU 10H
CTC_C1 EQU 11H
CTC_C2 EQU 12H
CTC_C3 EQU 13H
; CTC control word and time constant
C0INI EQU 17H ; 00010111
C0TCNT EQU 00H ; 00000000(256)
C1INI EQU 37H ; 00110111
C1TCNT EQU 80H ; 10000000(128)
C2INI EQU 37H ; 00110111
C2TCNT EQU 00H ; 00000000(256)
org 0h
ld sp,STKT
jp start
org 100h
start:
call INIT_CTC
main:
;
nop
;
jp main
;*****************************
INIT_CTC:
push af
push bc
; CTC channel 0
ld a,C0INI
ld c,CTC_C0
out (c),a
ld a,C0TCNT
out (c),a
; CTC channel 1
ld a,C1INI
ld c,CTC_C1
out (c),a
ld a,C1TCNT
out (c),a
; CTC channel 2
ld a,C2INI
ld c,CTC_C2
out (c),a
ld a,C2TCNT
out (c),a
;
pop bc
pop af
ret
end
Z80CTC、Z80PIOのテスト用プログラムを作成したので
信号を引き出すための基板を半田付けしました。
50ピンフラットケーブルを利用してZ80基板と接続します。
Z80基板側
コネクタ基板側
Z80CTCのコネクタは、次のように信号を配置。
1 Vcc
2 (no signal)
3 CLK/TRG0
4 ZC/TO0
5 CLK/TRG1
6 ZC/TO1
7 CLK/TRG2
8 ZC/TO2
9 CLK/TRG3
10 GND
チャネル0から2は、利用する信号がピンの
上下に並ぶ配置にしています。
PIOの配置は、以下。
1 Vcc 1 Vcc 1 Vcc 1 Vcc 1 Vcc
2 PA7 2 PB7 2 PC7 2 PD7 2 PE7
3 PA6 3 PB6 3 PC6 3 PD6 3 PE6
4 PA5 4 PB5 4 PC5 4 PD5 4 PE5
5 PA4 5 PB4 5 PC4 5 PD4 5 PE4
6 PA3 6 PB3 6 PC3 6 PD3 6 PE3
7 PA2 7 PB2 7 PC2 7 PD2 7 PE2
8 PA1 8 PB1 8 PC1 8 PD1 8 PE1
9 PA0 9 PB0 9 PC0 9 PD0 9 PE0
10 GND 10 GND 10 GND 10 GND 10 GND
Z80CTCの動作テスト用に、27C256にファームウエアを
書き込んで、接続します。
ゼロプレッシャソケットは、何度もROMを交換するので
ROMの足を痛めないために使っています。ROMは、27C256
を利用しました。
ファームウエアは、分周したクロックを出力する仕様
なので、マルチメータについている周波数カウンタで
周波数を測定します。
周波数カウンタの表示をみる限りでは、プログラム通り
に、動作しているとわかります。端数があるはずですが
1Hzの精度が出ていれば、充分でしょう。
周波数カウンタの他に、圧電スピーカを利用しても
Z80CTCの動作を確認できます。
写真のスピーカは、¥100ショップで入手してきた
スピーカです。インピーダンスが4Ωから32Ωくらい
ですから、アンプをつけないと音が小さいです。
1kHz前後なら、クリップワイヤーでZ80CTC出力を直接
接続して、微かに聞こえます。
今度は、PIOの動作テストをしてみます。
スイッチとLEDを載せた基板を利用します。
CPLD/FPGAで利用しているI/O基板ですが
コネクタ仕様をあわせているので、流用
できます。
PIOのテストは、ポートAを入力、他のポートを出力にし
ポートAの状態をポートBに反映させます。他のポート
は、内部カウンタの値を編集して出力します。
SENT EQU 8000h
STKT EQU SENT+2000h
PACON EQU 54h
PBCON EQU 55h
PCCON EQU 56h
PDCON EQU 34h
PECON EQU 44h
PADAT EQU 50h
PBDAT EQU 51h
PCDAT EQU 53h
PDDAT EQU 30h
PEDAT EQU 40h
org 0h
; set stack pointer
ld sp,STKT
jp start
org 100h
start:
; initialize PIO
call INIT_PIO
; clear counter
ld b,0
; endless loop
main:
; get data
in a,(PADAT)
; inverse
cpl
; put data
out (PBDAT),a
; counter handling
ld a,b
out (PCDAT),a
xor 0ffh
out (PDDAT),a
xor 0ffh
out (PDDAT),a
; counter increment
inc b
; delay
call SWAIT
call SWAIT
call SWAIT
call SWAIT
call SWAIT
;
jr main
;*******************
INIT_PIO:
; PIOA (input)
xor a
out (PACON),a
; PIOB (output)
or 0ffh
out (PBCON),a
; PIOC , PIOD , PIOE (output)
out (PCCON),a
out (PDCON),a
out (PECON),a
; initialize data
xor 0fh
out (PCCON),a
xor 0ffh
out (PDCON),a
xor 0ffh
out (PECON),a
;
ret
SWAIT:
; store
push bc
;
ld b,255
SWAITP:
nop
djnz SWAITP
; resume
pop bc
ret
end
CPUを時間待ちでループさせるのは無駄なので
タイマー割込みを利用して、指定時間の経過
後、イベントフラグで通知するのが定石。
PIOに接続したLEDを、タイマー割込みにより
点滅させてみます。
Z80CTCは、モード2割込みに対応しているので
このモードを使います。
モード2割込みでは、割込み処理ルーチン(割込みハンドラ)の
エントリーアドレスが入っているメモリブロックの上位8ビット
をレジスタIに入れます。下位8ビットは、ペリフェラルが規定
するので、ペリフェラルの初期化時に指定します。
Z80CTCのチャネル1、3が割込みを発生させるとして
割込みハンドラを定義します。
org 1000h
THANDLE:
; store
push af
; load
ld a,(XFLAGS)
; set 2^0 bit
set 0,a
; store
ld (XFLAGS),a
; resume
pop af
; enable interrupt
ei
;
reti
org 1020h
THANDLE2:
; store
push af
; load
ld a,(XFLAGS)
; set 2^1 bit
set 1,a
; store
ld (XFLAGS),a
; resume
pop af
; enable interrupt
ei
;
reti
チャネル1、3の割込みハンドラのエントリーアドレスは
orgで指定されたので、割込みベクターは、次のように確定
します。
dw 0000h ; CTC_C0
dw 1000h ; CTC_C1
dw 0000h ; CTC_C2
dw 1020h ; CTC_C3
これらの割込みベクターが、どこにあるのかZ80が把握して
おかないと割込みが発生したとき、どこのアドレスからの
コードを実行すればよいか戸惑うことになります。
レジスタIで上位8ビットを指定し、下位8ビットを
ペリフェラルに出力させます。
今回は、0080hに割込みベクターをおくことにします。
メモリの内容は、次のように確定します。
org 80h
dw 0000h ; CTC_C0
dw 1000h ; CTC_C1
dw 0000h ; CTC_C2
dw 1020h ; CTC_C3
レジスタIは上位8ビットが0なので、次のように指定。
xor a
ld i,a
レジスタIに直接値を代入するのは、システム暴走を
発生させることがあるので、レジスタAを経由します。
Z80CTCは、割込みベクターをチャネル0から書込みます。
ld a,80h
out (CTC_C0),a
割込み関連初期設定が終われば、タイマー割込みの周期を
考えておきます。
チャネル1 周期4Hzで割込み発生
チャネル3 周期8Hzで割込み発生
この条件で、Z80CTCの初期化は以下。
INIT_CTC:
; store
push af
push bc
; set vector address
ld a,80h
out (CTC_C0),a
; channel 0 (timer mode)
ld a,17h
out (CTC_C0),a
; channel 0 (time constant)
; generate 1kHz
ld a,250
out (CTC_C0),a
; channel 1 (counter mode)
ld a,0d7h
out (CTC_C1),a
; channel 1 (time constant)
; generate 4Hz
; since connected between ZC/TO0 and CLK/TRG1
ld a,250
out (CTC_C1),a
; channel 2 (timer mode)
ld a,17h
out (CTC_C2),a
; channel 2 (time constant)
; generate 2kHz
ld a,125
; channel 3 (counter mode)
ld a,0d7h
out (CTC_C3),a
; channel 3 (time constant)
; generate 8Hz
; since connected between ZC/TO2 and CLK/TRG3
ld a,250
out (CTC_C3),a
; resume
pop bc
pop af
ret
4MHzをタイマーモードのプリスケーラで1/16と250kHzを生成。
分周器で250分周で1kHzのクロックを生成。このクロックは
チャネル0、2で生成します。各ZC/TOをチャネル1、3の
CLK/TRGに接続します。
チャネル1、3をカウンタモードで動かし、1kHzを250、125
分周して4Hz、8Hz周期のタイマー割込みを発生させます。
割込み発生をイベントフラグで通知するように割込みハンドラを定義済み。
イベントフラグを、割込みハンドラと通知を受ける
ルーチンのどちらからでもアクセスできるように
グローバル変数としておきます。
フラグは、論理値をセット、クリアするのでSRAM領域に
配置します。
org 8000h
XFLAGS DS 1
TSTAT DS 1
VSTAT DS 1
タイマー割込みは、2種あるので4HzはXFLAGSの0ビット目
8HzはXFLAGSの1ビット目を使います。
タイマー割込みハンドラでは、フラグのセットだけ
通知を受けるルーチンでは、リセットだけと規約を
決めて使います。
イベントフラグの通知がきたとき、どうするかを定義。
main:
; load flags
ld a,(XFLAGS)
; judge timer interrupt
bit 0,a
jr z,main1
; clear 2^0 bit
res 0,a
ld (XFLAGS),a
; impress
call IPROC
main1:
; load flags
ld a,(XFLAGS)
; judge timer interrupt
bit 1,a
jr z,main2
; clear 2^1 bit
res 1,a
ld (XFLAGS),a
; impress
call IPROCX
main2:
;
jr main
イベントフラグがセットされていたなら、リセットして
対応するサブルーチンに処理を一任。
タイマー割込み発生で仕事をするサブルーチンは、以下。
IPROC:
; store
push af
; get now
ld a,(VSTAT)
; inverse
xor a
; store
ld (VSTAT),a
; impress
out (PCDAT),a
; resume
pop af
;
ret
IPROCX:
; store
push af
; get now
ld a,(TSTAT)
; inverse
xor a
; store
ld (TSTAT),a
; impress
out (PEDAT),a
; resume
pop af
;
ret
4Hzのタイマー割込みでは、レジスタの値を反転するので
8個のLEDが同時に点灯、消灯になります。
8Hzのタイマー割込みでも、8個のLEDが同時に点灯、消灯と
なります。タイマーの割込み周期の違いで、ブリンク周期が
異なります。
レジスタの初期化とPIOの設定などを含めて、まとめると
アセンブリ言語のソースコードは以下となります。
SENT EQU 8000h
STKT EQU SENT+2000h
; CTC I/O address
CTC_C0 EQU 10H
CTC_C1 EQU 11H
CTC_C2 EQU 12H
CTC_C3 EQU 13H
; PIO I/O address
PACON EQU 54h
PBCON EQU 55h
PCCON EQU 56h
PDCON EQU 34h
PECON EQU 44h
PADAT EQU 50h
PBDAT EQU 51h
PCDAT EQU 53h
PDDAT EQU 30h
PEDAT EQU 40h
;***********************
; reset entry
;***********************
org 0h
ld sp,STKT
jp start
;++++++++++++++++++
; interrupt vector
;++++++++++++++++++
org 80h
dw 0000h ; CTC_C0
dw 1000h ; CTC_C1
dw 0000h ; CTC_C2
dw 1020h ; CTC_C3
;========================
org 100h
start:
;
call INIT_CTC
call INIT_PIO
; set interrupt entry address
xor a
ld i,a
; set MODE 2 interrupt
im 2
; clear flags
xor a
ld (XFLAGS),a
; enable interrupt
ei
; endless loop
main:
; load flags
ld a,(XFLAGS)
; judge timer interrupt
bit 0,a
jr z,main1
; clear 2^0 bit
res 0,a
ld (XFLAGS),a
; impress
call IPROC
main1:
; load flags
ld a,(XFLAGS)
; judge timer interrupt
bit 1,a
jr z,main2
; clear 2^1 bit
res 1,a
ld (XFLAGS),a
; impress
call IPROCX
main2:
;
jr main
;*******************
INIT_CTC:
; store
push af
push bc
; set vector address
ld a,80h
out (CTC_C0),a
; channel 0 (timer mode)
ld a,17h
out (CTC_C0),a
; channel 0 (time constant)
; generate 1kHz
ld a,250
out (CTC_C0),a
; channel 1 (counter mode)
ld a,0d7h
out (CTC_C1),a
; channel 1 (time constant)
; generate 4Hz
; since connected between ZC/TO0 and CLK/TRG1
ld a,250
out (CTC_C1),a
; channel 2 (timer mode)
ld a,17h
out (CTC_C2),a
; channel 2 (time constant)
; generate 2kHz
ld a,125
; channel 3 (counter mode)
ld a,0d7h
out (CTC_C3),a
; channel 3 (time constant)
; generate 8Hz
; since connected between ZC/TO2 and CLK/TRG3
ld a,250
out (CTC_C3),a
; resume
pop bc
pop af
ret
INIT_PIO:
; store
push af
; PIOA (input mode)
xor a
out (PACON),a
; PIOB (output mode)
or 0ffh
out (PBCON),a
; PIOC , PIOD , PIOE (output mode)
out (PCCON),a
out (PDCON),a
out (PECON),a
; initialize data
xor 00fh
out (PCCON),a
xor 0ffh
out (PDCON),a
xor 0ffh
out (PECON),a
; resume
pop af
ret
IPROC:
; store
push af
; get now
ld a,(VSTAT)
; inverse
xor a
; store
ld (VSTAT),a
; impress
out (PCDAT),a
; resume
pop af
;
ret
IPROCX:
; store
push af
; get now
ld a,(TSTAT)
; inverse
xor a
; store
ld (TSTAT),a
; impress
out (PEDAT),a
; resume
pop af
;
ret
;********************
; interrupt handler
;********************
org 1000h
THANDLE:
; store
push af
; load flag
ld a,(XFLAGS)
; set flag
set 0,a
; store flag
ld (XFLAGS),a
; resume
pop af
; enable interrupt
ei
;
reti
org 1020h
THANDLE2:
; store
push af
; load flag
ld a,(XFLAGS)
; set flag
set 1,a
; store flag
ld (XFLAGS),a
; resume
pop af
; enable interrupt
ei
;
reti
;*******************
; data area in SRAM
;*******************
org 8000h
XFLAGS DS 1
TSTAT DS 1
VSTAT DS 1
end
目次
前
次