今回は、SPIによるSDCARDの初期化/読み書きについて、モニタに組み込んでいきたいと思います。
SDCARDは3.3V仕様なので、電圧変換内蔵のカードアダプタで接続します。
実際に接続するのは、PIOのポートAを使用します。
まずは、PIOのポートアドレスを定義します。
;; Z80 PIO
PIOAD .equ 0x88 ;PIO-A PORT DATA REG
PIOAC .equ 0x89 ;PIO-A PORT CONTL REG
PIOBD .equ 0x8a ;PIO-B PORT DATA REG
PIOBC .equ 0x8b ;PIO-B PORT CONTL REG
SPIでの通信のための端子を定義します。
実際には、PIOのポートAに接続される端子を定義します。
上位4ビットは出力として定義され、DI、CS、CLKを定義します。
下位4ビットは入力として定義され、DOを定義します。
;Z80 PIO-A OUTPUT-PORT
S_DI .equ 7 ;0b10000000 D7
S_CS .equ 6 ;0b01000000 D6
S_CLK .equ 5 ;0b00100000 D5
;Z80 PIO-A INPUT-PORT
DO .equ 0 ;0b00000001 D0
PIOの初期化ルーチンでは、ポートA,Bともモード3に設定、ポートAの上位4bitを出力に、下位4bitは入力に、ポートBは全ビット入力に設定。両ポートとも割り込みは設定していません。
pio_init:
;; PIO-A PORT INIT
ld a,0x00 ;int bector set
out (PIOAC),a
ld a,0b11001111 ;mode 3 set(bit control)
out (PIOAC),a
ld a,0b00001111 ;portA 7-4 output 3-0 input
out (PIOAC),a
ld a,0b00000111 ;int disple
out (PIOAC),a
ld a,0b11111111 ;mask bit
out (PIOAC),a
;; PIO-B PORT INIT
ld a,0x00 ;int bector set
out (PIOBC),a
ld a,0b11001111 ;mode 3 set(bit control)
out (PIOBC),a
ld a,0b11111111 ;portB 7-0 input
out (PIOBC),a
ld a,0b00000111 ;int disple
out (PIOBC),a
ld a,0b11111111 ;mask bit
out (PIOBC),a
ret
以下、SPIによるSDCARDの初期化手順は、Z8S180、TMPZ84C015、Z80+8251+8255とも重複しますが、今回はZ80+8251+8255の記事をもとに初期化手順を作成しました。
初期化の手順にあたってはELM by ChaNさんの「MMC/SDCの使い方」のほか、いろんなサイトをご参考にさせていただきました。貴重な情報ありがとうございます。
初期化の手順の大まかな手順は次のようになります。
(過去記載のZ8S180、TMPZ84C015の初期化手順と同じです。)
1、DI、CSを”H"してCLKを74クロック以上、発行する。(ここでは80クロック)
2、CMD0を発行する。(ソフトウェアリセットしSPIモードに入る)CRCは有効
3、CMD8を発行する。(SD Ver2以上かチェック)戻り値が0x1AAであればSDVer2以上)
4、CMD55を発行する。(次のコマンドがアプリケーションコマンドであることを知らせる。)
5、ACMD41を発行する。(初期化開始、レスポンス0x00が戻るまでコマンドを繰り返す。)
6、CMD58を発行する。(初期化完了及びSDHCかVer2を確認する。)
7、初期化終了
初期化の最初は、CLKを80クロック出力します。この時、DIは”H"、CSも”H"レベルにします。
spi_card_init:
xor a
set S_CS,a ;CS="H"
set S_DI,a ;DI="H"
out (PIOAD),a
ld b,80 ;80 clok output
call loopspii
80クロックは loopspiiで出力します。
コール前に Bレジスタに80を設定し、CLKに”L"、続いて”H"を設定、djnzでループしました。
loopspii:
res S_CLK,a ;CLK L
out (PIOAD),a
nop
nop
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out (PIOAD),a
nop
nop
nop
nop
nop
djnz loopspii
ret
r1_resp:
call resp
cp 0xff
jr z,r1_resp
ret
80クロックを出力した後、CSを”L"にして選択をアクティブにします。
ここから、コマンドによる制御に移ります。
最初は”CMD0"コマンドを発行します。48ビット列で、8ビット*6で構成されています。
最初の8Bit がコマンドインデックスで0x40、8ビット*4が引数、最後の8ビットがCRCになっています。CMD0ではCRCが必衰ですが、このコマンドは固定なのでCRCは0x95に固定です。
cmd0: ;;48bit(6byte) Fixed length
.db 0x40 ;;command index
.db 0x00 ;;argument
.db 0x00 ;;argument
.db 0x00 ;;argument
.db 0x00 ;;argument
.db 0x95 ;;CRC
CMD0を発行します。戻り値が0x01でない場合は、初期化エラーとします。
call cmd0_out
cp 0x01
jp nz,init_err
実際のCMD0の発行ルーチンは次のようになります。
HLレジに先ほどのCMD0テーブルアドレスをセットします。
cmd_outでコマンドを発行し、そのレスポンスをr1_respで受け取ります。
レスポンスの内容を表示(動作確認のため)した後、復帰します。
cmd0_out:
ld hl,cmd0
call cmd_out
call r1_resp
push af
ld hl,cmd0_msg
call msgout
pop af
push af
call hex_a_disp
ld a,0x0d
call putchar
pop af
ret
cmd_outは、8ビットごとに、spi_8bitを6回コールします。
8bitごとのデータはDレジスタにセットされます。
cmd_out: ;command out
push hl
push bc
ld b,0x06 ;command line word count
cmd_out1:
ld d,(hl) ;command line area
call spi_8bit
inc hl
djnz cmd_out1
pop bc
pop hl
ret
spi_8bitは、Dレジスタの7bit目を左シフトしキャリーフラグにセット(rlc d)し、このキャリーフラグの内容を右シフトしAレジスタの7bit目にセット(rra)します。CLKを”L"に変化させるとともに、7bit目のDIを出力します(パルスの立下り)。
時間稼ぎをした後、CLKを”H"にするとともに、ポートCの内容を読み込みます。(パルスの立ち上がり)
読み込まれたデータのAレジスタの0bit目のDOは、右シフトし(rrca)キャリーフラグにセットし、このキャリ―フラグをEレジスター左シフトして0bit目に格納します。この動作を8回繰り返し、8ビットのDレジスタの内容をシリアル出力し、入力されたシリアルデータをEレジスタに格納します。
spi_8bit: ;outdata Dreg,inputdata Ereg
push bc
ld c,0x00
ld b,0x08
loopspi:
xor a
rlc d
rra
res S_CLK,a ;CLK L
out (PIOAD),a
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out (PIOAD),a
in a,(PIOAD)
rrca
rl e
djnz loopspi
xor a
out (PIOAD),a
pop bc
ret
コマンドを発行した後のレスポンスの受信は、r1_respで行います。
レスポンスの受信は、DIを”H"にした(データとして”0xFF”)まま、先ほどのspi_8bitをコールし、戻り値(Eレジスタ)を取得します。
レスポンスr1_respでは、戻り値が0xFF以外の場合、respではそのまま、戻り値を返します。
r1_resp:
call resp
cp 0xff
jr z,r1_resp
ret
resp:
ld d,0xff
call spi_8bit
ld a,e
ret
CMD0を発行した後は、順にCMD8、CMD55、ACMD41、CMD58と発行していき、戻り値をチェックしていきます。
call cmd0_out
cp 0x01
jp nz,init_err
call cmd8_out
cp 0x01
jp nz,init_err
call cmd55_out
cp 0x01
jp nz,init_err
call acmd41_out
call cmd58_out
ld a,(r7)
bit 7,a
jp z,init_err
bit 6,a
jr z,SD_ver2
ld hl,sdhc_msg
init_msg:
call msgout
ret
SD_ver2:
ld hl,sd_ver2_msg
jr init_msg
CMD58では、レスポンスの30bit、31bit目をチェックします。
30bit目 0:SDVer2 1:SDHC
31bit目 0:初期化未完了 1:初期化完了
31ビット目が1であれば、初期化完了です。
SDCARDの1ブロックリード(512byte)は、シングルブロック呼び出しcmd17コマンドで行いました、
cmd17を発行するまえに、呼び出しブロックを指定します。
Ver2ではアドレス指定、SDHCでは1ブロック512byteごとのブロック番号を指定します。
SDCARDとして、SDHCでしか検証していませんので、初期化で”SDHC"の表示のあるSDHCカードを使用してください。
ブロック指定は、4バイトありますが、ここでは、2バイトだけ(HLレジスタ)指定しています。
m_cmd17:
.db 0x51
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
なお、cmd17とシングルブロック書き込みcmd24は、前述のようにブロック指定があるので、ROM領域から、RAM領域にコピーしています。
cmd17_24_copy:
ld b,0x06
ld hl,m_cmd17
ld de,cmd17
cmd17_copy:
ld a,(HL)
ld (DE),a
inc hl
inc de
djnz cmd17_copy
ld b,0x06
ld hl,m_cmd24
ld de,cmd24
cmd24_copy:
ld a,(HL)
ld (DE),a
inc hl
inc de
djnz cmd24_copy
ret
.org 0xff00
cmd17:
.db 0x51
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
前もって指定された読み出し指定ブロック(HLレジスタ)をcmdコマンドのワークエリアに設定します。
Ver2かSDHCかの区分は、初期化実行後のワークアエリアr7に保存されているのでこの値をチェックします。
spi_read1:
ld a,(r7)
bit 6,a
jp z,read_SD_ver2
ld a,h ;SDHC
ld (cmd17+03),a
ld a,l
ld (cmd17+04),a
jr spi_read2
read_SD_ver2:
ld a,h ;Ver2
ld (cmd17+02),a
ld a,l
ld (cmd17+03),a
spi_read2:
ld hl,save_addr_msg
call msgout
call input_hl
cp 0x00
jr z,cmd17_out
call cr
xor a
ret
まずは、ダミーデータ(0xff)でSPIの同期を取ります。
次に、cmd17コマンドを発行します。レスポンスが0x00であれば、エラーを返します。レスポンスがデータスタート0xfeを返すまで、待ちます。
データスタート0xfeを返したら、512byteの受信を行います。
ここでは、256byt*2回で受信しています。
受信データは「call resp」で1byteづつ受け取ります。
512byte(256byte*2回)受けとったら、CRC 2byteを受信しますが、ここではCRCは計算していないので、CRCは捨てます。
これで、データブロックは受信完了となります。
最後に 0xffを発行します。
cmd17_out:
call call_yes_msg
call getchar
cp "y"
jp nz,spi_ret
push hl
call dummy_data ;dummy data(0xff) out
ld hl,cmd17
call cmd_out ;cmd17 Issue
call r1_resp
cp 0x00 ;response is 0x00 read mode OK?
jr nz,cmd17_err
cmd17_st:
call r1_resp ;read data start response?
cp 0xfe ;data start byte 0xfe?
jr nz,cmd17_st
ld b,0x00 ;read data size 256byte
pop hl ;read data buff address
cmd17_r:
call resp ;read data
ld (hl),a
inc hl
djnz cmd17_r
ld b,0x00
cmd17_r2:
call resp
ld (hl),a ;read data
inc hl
djnz cmd17_r2
call resp ;crc Skipping read
call resp ;crc Skipping read
ld d,0xff ;dummy data 0xff(cs low)
call spi_8bit
続いて、書き込みですが、ここではシングルブロック書き込みcmd24コマンドを用いています。
読み込みcmd17と同様に、cmd24コマンドのワークエリアに書き込みブロックを指定します。(HLレジスター)
spi_write1:
ld a,(r7)
bit 6,a
jp z,write_SD_ver2
ld a,h ;SDHC
ld (cmd24+03),a
ld a,l
ld (cmd24+04),a
jr spi_write2
write_SD_ver2: ;Ver2
ld a,h
ld (cmd24+02),a
ld a,l
ld (cmd24+03),a
同期用のダミーデータを発行したのち、cmd24コマンドを発行します。
レスポンスが0x00であれば、エラーを返します。レスポンスがデータスタート0xfeを返すまで、待ちます。
データスタート0xfeを返したら、512byteの送信を行います。
ここでは、256byt*2回で送信しています。
送信データは「call spi_8bit」で1byteづつ送信します。
512byte(256byte*2回)送信したら、CRC 2byteを送信しますが、ここではCRCは計算していないので、CRCはダミーの0xffを送信しています。
CRC送信後レスポンスをチェックします。レスポンス0x05以外は送信エラーになります。
レスポンス0x05が内部の書き込み完了となる0x00まで待ちます。
これで書き込み完了となります。
最後に 0xffを発行します。
cmd24_out:
call call_yes_msg
call getchar
cp "y"
jp nz,spi_ret
push hl
call dummy_data
ld hl,cmd24
call cmd_out
call r1_resp
cp 0x00
jp nz,cmd24_err
ld d,0xfe
call spi_8bit
pop hl
ld b,0x00
cmd24_w:
ld d,(hl)
inc hl
call spi_8bit
djnz cmd24_w
ld b,0x00
cmd24_w2:
ld d,(hl)
inc hl
call spi_8bit
djnz cmd24_w2
ld d,0xff
call spi_8bit ;crc
call spi_8bit ;crc
call r1_resp
and 0x0f
cp 0x05
jr nz,cmd24_err2
cmd24_wch:
call r1_resp
cp 0x00
jr z,cmd24_wch
call dummy_data
実際にモニタで初期化、リードライトを行ってみます。
初期化は aiコマンドです。初期化がうまくいくと最後にカードの種類を表示します。
Monitor Z80+SIO+PIO ver0.71(SPI) by Pinecone 2020/09/27
>a spi(sd-card) Initialize : Yes:
CMD0:01
CMD8:01000001AA
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:00
CMD58:00C0FF8000
:SDHC
OK
>
SDHCで認識されました。
最初のブロック(0x0000)を読み込んでみます。
読み込みは arコマンドで続けて 読み込みブロック、読み込み先アドレスを指定します。ここでは ブロック0x0000をアドレス0x9000に1ブロック読み込みます。
>a read block No:0000 save addr:9000 Yes:
addr +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
9000 C3 5C DF C3 58 DF 7F 00 20 20 20 20 20 20 20 20
9010 20 20 20 20 20 20 20 20 43 4F 50 59 52 49 47 48
9020 54 20 28 43 29 20 31 39 37 39 2C 20 44 49 47 49
9030 54 41 4C 20 52 45 53 45 41 52 43 48 20 20 00 00
9040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
9050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
9060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
9070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
9080 00 00 00 00 00 00 00 00 08 DC 00 00 5F 0E 02 C3
9090 05 00 C5 CD 8C DC C1 C9 3E 0D CD 92 DC 3E 0A C3
90A0 92 DC 3E 20 C3 92 DC C5 CD 98 DC E1 7E B7 C8 23
90B0 E5 CD 8C DC E1 C3 AC DC 0E 0D C3 05 00 5F 0E 0E
90C0 C3 05 00 CD 05 00 32 EE E3 3C C9 0E 0F C3 C3 DC
90D0 AF 32 ED E3 11 CD E3 C3 CB DC 0E 10 C3 C3 DC 0E
90E0 11 C3 C3 DC 0E 12 C3 C3 DC 11 CD E3 C3 DF DC 0E
90F0 13 C3 05 00 CD 05 00 B7 C9 0E 14 C3 F4 DC 11 CD
addr +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
9100 E3 C3 F9 DC 0E 15 C3 F4 DC 0E 16 C3 C3 DC 0E 17
9110 C3 05 00 1E FF 0E 20 C3 05 00 CD 13 DD 87 87 87
9120 87 21 EF E3 B6 32 04 00 C9 3A EF E3 32 04 00 C9
9130 FE 61 D8 FE 7B D0 E6 5F C9 3A AB E3 B7 CA 96 DD
9140 3A EF E3 B7 3E 00 C4 BD DC 11 AC E3 CD CB DC CA
9150 96 DD 3A BB E3 3D 32 CC E3 11 AC E3 CD F9 DC C2
9160 96 DD 11 07 DC 21 80 00 06 80 CD 42 E0 21 BA E3
9170 36 00 23 35 11 AC E3 CD DA DC CA 96 DD 3A EF E3
9180 B7 C4 BD DC 21 08 DC CD AC DC CD C2 DD CA A7 DD
9190 CD DD DD C3 82 DF CD DD DD CD 1A DD 0E 0A 11 06
91A0 DC CD 05 00 CD 29 DD 21 07 DC 46 23 78 B7 CA BA
91B0 DD 7E CD 30 DD 77 05 C3 AB DD 77 21 08 DC 22 88
91C0 DC C9 0E 0B CD 05 00 B7 C8 0E 01 CD 05 00 B7 C9
91D0 0E 19 C3 05 00 11 80 00 0E 1A C3 05 00 21 AB E3
91E0 7E B7 C8 36 00 AF CD BD DC 11 AC E3 CD EF DC 3A
91F0 EF E3 C3 BD DC 11 28 DF 21 00 E4 06 06 1A BE C2
>
次に 先ほど読み込んだ最初のブロック0x0000をモニタ0x0100から512byte書き込みしてみます。
読み込みは awコマンドで続けて 書き込みブロック、書き込み先アドレスをしてします。ここでは ブロック0x0000にアドレス0x0100から1ブロック書み込みます。
>a write block No:0000 write addr:0100 Yes:
addr +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
0100 31 00 00 CD FE 06 CD 11 07 21 4E 07 CD E0 06 3E
0110 3E CD F3 06 CD EA 06 CD F3 06 FE 3F CC 4F 01 FE
0120 64 CC 44 02 FE 6D CC 5A 02 FE 6C CC B1 01 FE 6A
0130 CC 5C 01 FE 69 CC 8E 02 FE 63 CC 86 01 FE 61 CC
0140 CD 02 FE 0D 28 C9 FE 00 28 C5 CD 56 01 18 C0 21
0150 88 07 CD E0 06 C9 3E 0D CD F3 06 C9 3E 20 CD F3
0160 06 CD 50 06 FE 00 20 1A 3E 20 CD F3 06 3E 79 CD
0170 F3 06 3E 3A CD F3 06 CD EA 06 FE 79 20 04 CD 56
0180 01 E9 CD 56 01 C9 3E 20 CD F3 06 CD 50 06 FE 00
0190 20 F0 3E 20 CD F3 06 3E 79 CD F3 06 3E 3A CD F3
01A0 06 CD EA 06 FE 79 20 DA CD 56 01 11 B0 01 D5 E9
01B0 C9 CD EB 01 FE FF 28 19 FE 01 20 F5 3E 0D CD F3
01C0 06 3E 4F CD F3 06 3E 4B CD F3 06 3E 0D CD F3 06
01D0 C9 3E 0D CD F3 06 3E 45 CD F3 06 3E 52 CD F3 06
01E0 3E 52 CD F3 06 3E 0D CD F3 06 C9 3E 0D CD F3 06
01F0 16 00 CD EA 06 FE 3A 20 48 CD 4B 06 45 7A 80 57
addr +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
0200 CD 50 06 E5 DD E1 7A 85 84 57 CD 4B 06 7D FE 00
0210 20 20 CD 4B 06 DD 75 00 DD 23 7D 82 57 10 F3 CD
0220 4B 06 7A 85 FE 00 20 19 CD EA 06 FE 0A 20 12 3E
0230 00 C9 FE 01 20 0B CD 4B 06 7D FE FF 20 03 3E 01
0240 C9 3E FF C9 3E 20 CD F3 06 CD 50 06 FE 00 28 03
0250 FD E5 E1 CD 76 06 E5 FD E1 C9 3E 20 CD F3 06 CD
0260 50 06 FE 00 28 06 3E 0D CD F3 06 C9 3E 20 CD F3
0270 06 7E CD A7 06 3E 20 CD F3 06 E5 CD 4B 06 FE 00
0280 28 03 E1 AF C9 4D E1 71 3E 0D CD F3 06 C9 3E 20
0290 CD F3 06 CD 4B 06 FE 00 28 06 3E 0D CD F3 06 C9
02A0 3E 20 CD F3 06 06 00 4D ED 78 CD A7 06 3E 20 CD
02B0 F3 06 CD 4B 06 FE 00 28 02 AF C9 7D ED 79 3E 0D
02C0 CD F3 06 C9 E5 21 F6 08 CD E0 06 E1 C9 CD EA 06
02D0 FE 69 CC 7E 04 FE 72 CC E0 02 FE 77 CC D0 03 C9
02E0 21 05 09 CD E0 06 CD 50 06 FE 00 28 05 CD 56 01
02F0 AF C9 3A 0C FF CB 77 CA 04 03 7C 32 03 FF 7D 32
>
書き込みできたみたいです。
再度読み込みして、書き込みと読み込みが内容が同じか確認します。
ブロック0x0000をアドレス0x9000に1ブロック読み込みます。
>a read block No:0000 save addr:9000 Yes:
addr +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
9000 31 00 00 CD FE 06 CD 11 07 21 4E 07 CD E0 06 3E
9010 3E CD F3 06 CD EA 06 CD F3 06 FE 3F CC 4F 01 FE
9020 64 CC 44 02 FE 6D CC 5A 02 FE 6C CC B1 01 FE 6A
9030 CC 5C 01 FE 69 CC 8E 02 FE 63 CC 86 01 FE 61 CC
9040 CD 02 FE 0D 28 C9 FE 00 28 C5 CD 56 01 18 C0 21
9050 88 07 CD E0 06 C9 3E 0D CD F3 06 C9 3E 20 CD F3
9060 06 CD 50 06 FE 00 20 1A 3E 20 CD F3 06 3E 79 CD
9070 F3 06 3E 3A CD F3 06 CD EA 06 FE 79 20 04 CD 56
9080 01 E9 CD 56 01 C9 3E 20 CD F3 06 CD 50 06 FE 00
9090 20 F0 3E 20 CD F3 06 3E 79 CD F3 06 3E 3A CD F3
90A0 06 CD EA 06 FE 79 20 DA CD 56 01 11 B0 01 D5 E9
90B0 C9 CD EB 01 FE FF 28 19 FE 01 20 F5 3E 0D CD F3
90C0 06 3E 4F CD F3 06 3E 4B CD F3 06 3E 0D CD F3 06
90D0 C9 3E 0D CD F3 06 3E 45 CD F3 06 3E 52 CD F3 06
90E0 3E 52 CD F3 06 3E 0D CD F3 06 C9 3E 0D CD F3 06
90F0 16 00 CD EA 06 FE 3A 20 48 CD 4B 06 45 7A 80 57
addr +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
9100 CD 50 06 E5 DD E1 7A 85 84 57 CD 4B 06 7D FE 00
9110 20 20 CD 4B 06 DD 75 00 DD 23 7D 82 57 10 F3 CD
9120 4B 06 7A 85 FE 00 20 19 CD EA 06 FE 0A 20 12 3E
9130 00 C9 FE 01 20 0B CD 4B 06 7D FE FF 20 03 3E 01
9140 C9 3E FF C9 3E 20 CD F3 06 CD 50 06 FE 00 28 03
9150 FD E5 E1 CD 76 06 E5 FD E1 C9 3E 20 CD F3 06 CD
9160 50 06 FE 00 28 06 3E 0D CD F3 06 C9 3E 20 CD F3
9170 06 7E CD A7 06 3E 20 CD F3 06 E5 CD 4B 06 FE 00
9180 28 03 E1 AF C9 4D E1 71 3E 0D CD F3 06 C9 3E 20
9190 CD F3 06 CD 4B 06 FE 00 28 06 3E 0D CD F3 06 C9
91A0 3E 20 CD F3 06 06 00 4D ED 78 CD A7 06 3E 20 CD
91B0 F3 06 CD 4B 06 FE 00 28 02 AF C9 7D ED 79 3E 0D
91C0 CD F3 06 C9 E5 21 F6 08 CD E0 06 E1 C9 CD EA 06
91D0 FE 69 CC 7E 04 FE 72 CC E0 02 FE 77 CC D0 03 C9
91E0 21 05 09 CD E0 06 CD 50 06 FE 00 28 05 CD 56 01
91F0 AF C9 3A 0C FF CB 77 CA 04 03 7C 32 03 FF 7D 32
>
読み書きの内容は同じになってました^^。
今回のモニタのソースとHEXファイルは次の通りです。
次回は、64KRAMのモニタへの移行コマンドととcp/mをブートするためのブートコマンドを実装して、最終的なモニタを完成したいと思います。
; Z80+SIO+PIO monitor(SPI) ver0.71 by Pinecone 2020/09/27
;
; Z80 cpu
; rom 0000h -- 7fffh
; ram 8000h -- ffffh
; External clock 4.9142MHz
; SIO serial communication A-CH
; extemal Clock 0.6144MHz (4.9152MHz TC74HC4040 1/8 Frequency division)
; Band Rate:38400 8bits 1Stopbits none Parity (81N)
; assembler
; program start 0000H
; main 0100H
;
; assemblers ASxxxx and ASlink V5.10
; file name z80_SIO_PIO_spi_moni071.asm
; $ asz80 -l -s -o z80_SIO_PIO_spi_moni071.asm
; $ aslink -i z80_SIO_PIO_spi_moni071
; $ rom-writer TL866-2 plus z80_SIO_PIO_spi_moni071.ihx
;
.z80
;; Z80 PIO
PIOAD .equ 0x88 ;PIO-A PORT DATA REG
PIOAC .equ 0x89 ;PIO-A PORT CONTL REG
PIOBD .equ 0x8a ;PIO-B PORT DATA REG
PIOBC .equ 0x8b ;PIO-B PORT CONTL REG
;; Z80 SIO
SIOAD .equ 0x84 ;SIO A-CH DATA REG
SIOAC .equ 0x85 ;SIO A-CH CONTL REG
SIOBD .equ 0x86 ;SIO B-CH DATA REG
SIOBC .equ 0x87 ;SIO B-CH CONTL REG
;Z80 PIO-A OUTPUT-PORT
S_DI .equ 7 ;0b10000000 D7
S_CS .equ 6 ;0b01000000 D6
S_CLK .equ 5 ;0b00100000 D5
;Z80 PIO-A INPUT-PORT
DO .equ 0 ;0b00000001 D0
.area TEST(ABS)
.org 0x0000
jp start
.org 0x100
start: ;cold start
ld sp,0x0000 ;stack pointer set
call sio_init ;serial channel initialize
call pio_init ;Parallel port initialize
ld hl,msg_op ;opening message display
call msgout
prompt: ld a,">" ;main routine
call putchar ;prompt display
call getchar
call putchar
cp "?" ;help ?
call z,help
cp "d" ;memory display?
call z,dump
cp "m" ;memory rewrite ?
call z,memory
cp "l" ;hex file load?
call z,loadhex
cp "j" ;address jump?
call z,jump
cp "i" ;i/o register rewite
call z,ioreg
cp "c"
call z,calling ;address call
cp "a"
call z,spi_card ;read/write spi sd-card
cp 0x0d
jr z,prompt
cp 0x00
jr z,prompt
call cr
jr prompt
help: ld hl,help_msg ;help ?
call msgout
ret
cr:
ld a,0x0d
call putchar
ret
jump: ;address jump?
ld a," "
call putchar
call input_hl ;dump address input
cp 0x00
jr nz,crret
ld a," "
call putchar
ld a,"y"
call putchar
ld a,":"
call putchar
call getchar
cp "y"
jr nz,crret
call cr
jp (HL)
crret:
call cr
ret
calling: ;address call?
ld a," "
call putchar
call input_hl ;call address input
cp 0x00
jr nz,crret
ld a," "
call putchar
ld a,"y"
call putchar
ld a,":"
call putchar
call getchar
cp "y"
jr nz,crret
call cr
ld de,callret
push de
jp (HL)
callret:
ret
loadhex:
call loadhexline ;load 1line Hex file
cp 0xff ;hex file read err
jr z,loadhexerr
cp 0x01 ;hex file end?
jr nz,loadhex
ld a,0x0d
call putchar
ld a,"O"
call putchar
ld a,"K"
call putchar
ld a,0x0d
call putchar
ret
loadhexerr:
ld a,0x0d ;hex file read skip
call putchar
ld a,"E"
call putchar
ld a,"R"
call putchar
ld a,"R"
call putchar
ld a,0x0d
call putchar
ret
loadhexline:
ld a,0x0d
call putchar
ld d,0x00 ;checksum count clr
call getchar ;record mark is ":"
cp ":"
jr nz,loadhexlineerr
call input_l ;data size 1byte
ld b,l ;checksum = checksum + data size
ld a,d
add b
ld d,a
call input_hl ;offset address 2byte
push hl
pop ix ;offset address HLreg >> IXreg
ld a,d ;checksum = checksum + address Low
add l
add h ;checksum = checksum + address Hi
ld d,a
call input_l ;record type
ld a,l
cp 0x00 ;data record
jr nz,checkrecord
;; *** data record job ****
data_hex:
call input_l ;read hex 1byte in Lreg(hex)
ld (ix),l ;offset address < hex data
inc ix ;offset address +1
ld a,l
add d ;cheksum Dreg = Dreg + Lreg
ld d,a
djnz data_hex ;Breg(data size) == 0?
call input_l ;chechsum OK?
ld a,d
add l
cp 0x00
jr nz,loadhexlineerr
call getchar
cp 0x0a ;load 1line hex LF?
jr nz,loadhexlineerr
ld a,0x00
ret
checkrecord: ;end record ?
cp 0x01
jr nz,loadhexlineerr
call input_l
ld a,l
cp 0xff
jr nz,loadhexlineerr
ld a,0x01
ret
loadhexlineerr:
ld a,0xff ;read record err (no support)
ret
dump: ;memory dump
ld a," "
call putchar
call input_hl ;dump address input
cp 0x00
jr z,dump1
push iy ;memory dump address set
pop hl
dump1:
call dump_hl ;memory dump
push hl ;memory address IY set
pop iy
ret
memory: ;memory change
ld a," " ;space
call putchar
call input_hl ;change memory address
cp 0x00
jr z,memory1 ;no address hex code
ld a,0x0d
call putchar
ret
memory1:
ld a," " ;current memory display
call putchar
ld a,(HL)
call hex_a_disp
ld a," "
call putchar
push hl
call input_l ;new memory conntents input
cp 0x00
jr z,memory2
pop hl
xor a
ret
memory2:
ld c,l ;memory contents update
pop hl
ld (hl),c
ld a,0x0d
call putchar
ret
ioreg: ;ioreg change
ld a," " ;space
call putchar
call input_l ;change i/o register
cp 0x00
jr z,ioreg1 ;no address hex code
ld a,0x0d
call putchar
ret
ioreg1:
ld a," " ;current i/o address display
call putchar
ld b,0x00
ld c,l
in a,(c)
call hex_a_disp
ld a," "
call putchar
call input_l ;new i/o conntents address input
cp 0x00
jr z,ioreg2
xor a
ret
ioreg2:
ld a,l ;new i/o address update
out (c),a
ld a,0x0d
call putchar
ret
call_yes_msg:
push hl
ld hl,yes_msg
call msgout
pop hl
ret
spi_card:
call getchar
cp "i"
call z,spi_init
cp "r"
call z,spi_read
cp "w"
call z,spi_write
ret
spi_read:
ld hl,read_block_no_msg
call msgout
call input_hl
cp 0x00
jr z,spi_read1
call cr
xor a
ret
spi_read1:
ld a,(r7)
bit 6,a
jp z,read_SD_ver2
ld a,h ;SDHC
ld (cmd17+03),a
ld a,l
ld (cmd17+04),a
jr spi_read2
read_SD_ver2:
ld a,h ;Ver2
ld (cmd17+02),a
ld a,l
ld (cmd17+03),a
spi_read2:
ld hl,save_addr_msg
call msgout
call input_hl
cp 0x00
jr z,cmd17_out
call cr
xor a
ret
cmd17_out:
call call_yes_msg
call getchar
cp "y"
jp nz,spi_ret
push hl
call dummy_data ;dummy data(0xff) out
ld hl,cmd17
call cmd_out ;cmd17 Issue
call r1_resp
cp 0x00 ;response is 0x00 read mode OK?
jr nz,cmd17_err
cmd17_st:
call r1_resp ;read data start response?
cp 0xfe ;data start byte 0xfe?
jr nz,cmd17_st
ld b,0x00 ;read data size 256byte
pop hl ;read data buff address
cmd17_r:
call resp ;read data
ld (hl),a
inc hl
djnz cmd17_r
ld b,0x00
cmd17_r2:
call resp
ld (hl),a ;read data
inc hl
djnz cmd17_r2
call resp ;crc Skipping read
call resp ;crc Skipping read
ld d,0xff ;dummy data 0xff(cs low)
call spi_8bit
;memory dump address
ld bc,0x0200
sbc hl,bc
;memory dump 512b
ld a,0x0d
call putchar
call hl_disp256 ;256bye dump
call putchar
call hl_disp256 ;256bye dump
call putchar
xor a
ret
cmd17_err:
pop hl
ld hl,cmd17_err_msg
call msgout
ret
hl_disp256:
push bc
ld b,0x00 ;dump data size 256bye
push hl
ld hl,dump_msg ;dump address msg output
call msgout
pop hl
ld a,h ;dump address HLreg
call hex_a_disp ;dump address output
ld a,l
call hex_a_disp
ld a," "
call putchar
call putchar
hl_disp256_loop:
ld a,(HL) ;dump addres data (HL)
inc HL
call hex_a_disp
ld a,b
cp 0x01 ;end dump size?
jr z,hl_disp256_loop1
ld a,b
and 0x0f
cp 0x01 ;0x?0-0x?f is 0x01(1line disp end?)
jr z,hl_disp256_cr
ld a," " ;space Insert
call putchar
jr hl_disp256_loop1
hl_disp256_cr:
ld a,0x0d
call putchar
ld a,h ;dump address HLreg
call hex_a_disp ;dump address output
ld a,l
call hex_a_disp
ld a," "
call putchar
call putchar
hl_disp256_loop1:
djnz hl_disp256_loop
ld a,0x0d
call putchar
pop bc
ret
spi_write:
ld hl,write_block_no_msg
call msgout
call input_hl
cp 0x00
jr z,spi_write1
call cr
xor a
ret
spi_write1:
ld a,(r7)
bit 6,a
jp z,write_SD_ver2
ld a,h ;SDHC
ld (cmd24+03),a
ld a,l
ld (cmd24+04),a
jr spi_write2
write_SD_ver2: ;Ver2
ld a,h
ld (cmd24+02),a
ld a,l
ld (cmd24+03),a
spi_write2:
ld hl,write_addr_msg
call msgout
call input_hl
cp 0x00
jr z,cmd24_out
call cr
xor a
ret
cmd24_out:
call call_yes_msg
call getchar
cp "y"
jp nz,spi_ret
push hl
call dummy_data
ld hl,cmd24
call cmd_out
call r1_resp
cp 0x00
jp nz,cmd24_err
ld d,0xfe
call spi_8bit
pop hl
ld b,0x00
cmd24_w:
ld d,(hl)
inc hl
call spi_8bit
djnz cmd24_w
ld b,0x00
cmd24_w2:
ld d,(hl)
inc hl
call spi_8bit
djnz cmd24_w2
ld d,0xff
call spi_8bit ;crc
call spi_8bit ;crc
call r1_resp
and 0x0f
cp 0x05
jr nz,cmd24_err2
cmd24_wch:
call r1_resp
cp 0x00
jr z,cmd24_wch
call dummy_data
ld bc,0x0200
sbc hl,bc
;memory dump 512b
ld a,0x0d
call putchar
call hl_disp256 ;256bye dump
call putchar
call hl_disp256 ;256bye dump
call putchar
xor a
ret
cmd24_err:
pop hl
cmd24_err2:
ld hl,cmd24_err_msg
call msgout
ret
spi_init:
call cmd17_24_copy
ld hl,spi_init_msg
call msgout
call call_yes_msg
call getchar
cp "y"
jp nz,spi_ret
call cr
call spi_card_init
ld hl,ok_msg
call msgout
ret
cmd17_24_copy:
ld b,0x06
ld hl,m_cmd17
ld de,cmd17
cmd17_copy:
ld a,(HL)
ld (DE),a
inc hl
inc de
djnz cmd17_copy
ld b,0x06
ld hl,m_cmd24
ld de,cmd24
cmd24_copy:
ld a,(HL)
ld (DE),a
inc hl
inc de
djnz cmd24_copy
ret
spi_card_init:
xor a
set S_CS,a ;CS="H"
set S_DI,a ;DI="H"
out (PIOAD),a
ld b,80 ;80 clok output
call loopspii
xor a
out (PIOAD),a ;CS="L" DI="L" CLK="L"
call cmd0_out
cp 0x01
jp nz,init_err
call cmd8_out
cp 0x01
jp nz,init_err
call cmd55_out
cp 0x01
jp nz,init_err
call acmd41_out
call cmd58_out
ld a,(r7)
bit 7,a
jp z,init_err
bit 6,a
jr z,SD_ver2
ld hl,sdhc_msg
init_msg:
call msgout
ret
SD_ver2:
ld hl,sd_ver2_msg
jr init_msg
cmd0_out:
ld hl,cmd0
call cmd_out
call r1_resp
push af
ld hl,cmd0_msg
call msgout
pop af
push af
call hex_a_disp
ld a,0x0d
call putchar
pop af
ret
cmd8_out:
call dummy_data
ld hl,cmd8
call cmd_out
call r1_resp
cp 0x01
ret nz
ld b,4
ld hl,r7
cmd8_r:
call resp
ld (hl),a
inc hl
djnz cmd8_r
cmd8_r_d:
ld hl,cmd8_msg
call msgout
ld a,0x01
call hex_a_disp
ld hl,r7
ld b,4
cmd8_r_d_loop:
ld a,(hl)
call hex_a_disp
inc hl
djnz cmd8_r_d_loop
ld a,0x0d
call putchar
ld a,0x01
ret
cmd55_out:
call dummy_data
ld hl,cmd55
call cmd_out
call r1_resp
push af
ld hl,cmd55_msg
call msgout
pop af
push af
call hex_a_disp
ld a,0x0d
call putchar
pop af
ret
acmd41_out:
call dummy_data
ld hl,acmd41 ;sd-card Initialize
call cmd_out
call r1_resp
cp 0x00
push af
ld hl,acmd41_msg
call msgout
pop af
push af
call hex_a_disp
ld a,0x0d
call putchar
pop af
ret z
call cmd55_out
jr acmd41_out
spi_ret:
call cr
ret
init_err:
ld hl,spi_init_err_msg
call msgout
call cr
jp start
cmd58_out:
call dummy_data
ld hl,cmd58
call cmd_out
call r1_resp
push af
ld b,4
ld hl,r7
cmd58_r:
call resp
ld (hl),a
inc hl
djnz cmd58_r
cmd58_r_d:
ld hl,cmd58_msg
call msgout
pop af
push af
call hex_a_disp
ld hl,r7
ld b,4
cmd58_r_d_loop:
ld a,(hl)
call hex_a_disp
inc hl
djnz cmd58_r_d_loop
ld a,0x0d
call putchar
pop af
ret
dummy_data:
xor a
set S_CS,a ;CS="H"
set S_DI,a ;DI="H"
out (PIOAD),a
ld b,8 ;1clok output
call loopspii
xor a
out (PIOAD),a
ret
loopspii:
res S_CLK,a ;CLK L
out (PIOAD),a
nop
nop
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out (PIOAD),a
nop
nop
nop
nop
nop
djnz loopspii
ret
r1_resp:
call resp
cp 0xff
jr z,r1_resp
ret
resp:
ld d,0xff
call spi_8bit
ld a,e
ret
cmd_out: ;command out
push hl
push bc
ld b,0x06 ;command line word count
cmd_out1:
ld d,(hl) ;command line area
call spi_8bit
inc hl
djnz cmd_out1
pop bc
pop hl
ret
spi_8bit: ;outdata Dreg,inputdata Ereg
push bc
ld c,0x00
ld b,0x08
loopspi:
xor a
rlc d
rra
res S_CLK,a ;CLK L
out (PIOAD),a
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out (PIOAD),a
in a,(PIOAD)
rrca
rl e
djnz loopspi
xor a
out (PIOAD),a
pop bc
ret
input_l: ;input Lreg hex (1byte)
push bc
ld b,0x02
jr input_loop
input_hl: ;input HLreg hex (2byte)
push bc
ld b,0x04
input_loop:
ld hl,0x0000 ;HL reg cler
jr input_hl2
shift_hl:
add hl,hl ;HL reg shift left 4bit
add hl,hl
add hl,hl
add hl,hl
input_hl2:
call getchar ;input ascii hex 1char
call putchar
call ascii_hex ;ascii hex 1char >> Areg
cp 0xff
jr z,input_hl_err
and 0x0f ;Areg low order 4bit >> Lreg
or l
ld l,a
djnz shift_hl
input_hl_end:
pop bc
xor a ;OK >> Areg 0x00
ret
input_hl_err:
ld a,0xff ;NG >> Areg 0xff
pop bc
ret
dump_hl: ;memory dump 1line(+0 -- +f)
ld a,0x0d
call putchar
push hl
ld hl,dump_msg ;dump address msg output
call msgout
pop hl
ld a,h ;dump address HLreg
call hex_a_disp ;dump address output
ld a,l
call hex_a_disp
ld a," "
call putchar
call putchar
ld b,0x10 ;address --> address +0f
hl_disp:
ld a,(HL) ;dump addres data (HL)
inc HL
call hex_a_disp
ld a," "
call putchar
djnz hl_disp
ld a,0x0d
call putchar
ret
hex_a_disp: ;Areg(HEX) >> putchar(areg)
push af
rrca ;7-4bit Right shift
rrca
rrca
rrca
call hex_ascii ;3-0bit Hex >> Hex ascii(0-F)
call putchar ;7-4bit putchar
pop af
call hex_ascii ;3-0bit Hex >> Hex ascii(0-F)
call putchar ;3-0bit putchar
ret
ascii_hex:
sub 0x30
jr c,err_hex
cp 0x0A ;0-9
jr c,hex_1_9
sub 0x11
cp 0x06 ;A-F
jr c,hex_A_F
sub 0x20
cp 0x06 ;a-f
jr nc,err_hex
hex_A_F:
add 0x0a
hex_1_9:
ret
err_hex:ld a,0xff
ret
hex_ascii: ;Areg(HEX) >> Areg(ascii code)
and a,0x0f
cp 0x0a
jr c,ascii0_9
add 0x37
ret
ascii0_9:
add 0x30
ret
msgout:
ld a,(hl) ;(HL)reg is output disp at 0x00
cp 0x00
ret z
call putchar
inc hl
jr msgout
getchar:
in a,(SIOAC)
bit 0,a
jr z,getchar
in a,(SIOAD)
ret
putchar:push af
putchar01:
in a,(SIOAC)
bit 2,a
jr z,putchar01
pop af
out (SIOAD),a
ret
;
sio_init:
ld b,0x0b
ld c,SIOBC
ld hl,SIO_INIT_TB_B
otir
ld b,0x09
ld c,SIOAC
ld hl,SIO_INIT_TB_A
otir
ret
pio_init:
;; PIO-A PORT INIT
ld a,0x00 ;int bector set
out (PIOAC),a
ld a,0b11001111 ;mode 3 set(bit control)
out (PIOAC),a
ld a,0b00001111 ;portA 7-4 output 3-0 input
out (PIOAC),a
ld a,0b00000111 ;int disple
out (PIOAC),a
ld a,0b11111111 ;mask bit
out (PIOAC),a
;; PIO-B PORT INIT
ld a,0x00 ;int bector set
out (PIOBC),a
ld a,0b11001111 ;mode 3 set(bit control)
out (PIOBC),a
ld a,0b11111111 ;portB 7-0 input
out (PIOBC),a
ld a,0b00000111 ;int disple
out (PIOBC),a
ld a,0b11111111 ;mask bit
out (PIOBC),a
ret
;
SIO_INIT_TB_A:
.db 0x18 ;ch RESET
.db 0x14 ;WR4 set ,int reset
.db 0b01000100 ;x16 8bitchar 1stopbit nonparity
.db 0x03 ;WR3 set
.db 0b11000001 ;rx 8bit char ,RxEnable
.db 0x05 ;WR5 set
.db 0b01101000 ;tx 8bit char ,TxEnable ,DTR=0 ,RTS=0
.db 0x11 ;WR1 set ,int reset
.db 0b00000000 ;non int
SIO_INIT_TB_B:
.db 0x18 ;ch RESET
.db 0x02 ;WR2 set
.db 0x00 ;int tabel 0x00
.db 0x14 ;WR4 set ,int reset
.db 0b01000100 ;x16 8bitchar 1stopbit nonparity
.db 0x03 ;WR3 set
.db 0b11000001 ;rx 8bit char ,RxEnable
.db 0x05 ;WR5 set
.db 0b01101000 ;tx 8bit char ,TxEnable ,DTR=0 ,RTS=0
.db 0x11 ;WR1 set ,int reset
.db 0b00000000 ;non int
msg_op: .str "Monitor Z80+SIO+PIO ver0.71(SPI) by Pinecone 2020/09/27"
.db 0x0d
.db 0x00
help_msg:
.db 0x0d
.str "? Help"
.db 0x0d
.str "d memory dump"
.db 0x0d
.str "m memory change address old new"
.db 0x0d
.str "l hex file load"
.db 0x0d
.str "j jump"
.db 0x0d
.str "i i/o register i/o-address old new"
.db 0x0d
.str "c call"
.db 0x0d
.str "ai spi(sd-card) Initialization"
.db 0x0d
.str "ar spi(sd-card) read (512byte/block) 0x0000-0xffff set"
.db 0x0d
.str "aw spi(sd-card) write (512byte/block) 0x0000-0xffff set"
.db 0x0d
.db 0x00
dump_msg:
.str "addr +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F"
.db 0x0d
.db 0x00
cmd0_msg:
.str "CMD0:"
.db 0x00
cmd8_msg:
.str "CMD8:"
.db 0x00
cmd55_msg:
.str "CMD55:"
.db 0x00
acmd41_msg:
.str "ACMD41:"
.db 0x00
cmd58_msg:
.str "CMD58:"
.db 0x00
yes_msg:
.str " Yes:"
.db 0x00
ok_msg:
.str "OK"
.db 0x0d
.db 0x00
err_msg:
.str "ERR"
.db 0x0d
.db 0x00
read_block_no_msg:
.str " read block No:"
.db 0x00
write_block_no_msg:
.str " write block No:"
.db 0x00
save_addr_msg:
.str " save addr:"
.db 0x00
write_addr_msg:
.str " write addr:"
.db 0x00
spi_init_err_msg:
.str "Spi Init Err"
.db 0x0d
.db 0x00
cmd17_err_msg:
.str "cmd17 Err"
.db 0x0d
.db 0x00
cmd24_err_msg:
.str "cmd24 Err"
.db 0x0d
.db 0x00
sdhc_msg:
.str ":SDHC"
.db 0x0d
.db 0x00
sd_ver2_msg:
.str ":SD Ver2"
.db 0x0d
.db 0x00
spi_init_msg:
.str " spi(sd-card) Initialize :"
.db 0x00
cmd0: ;;48bit(6byte) Fixed length
.db 0x40 ;;command index
.db 0x00 ;;argument
.db 0x00 ;;argument
.db 0x00 ;;argument
.db 0x00 ;;argument
.db 0x95 ;;CRC
;cmd1:
; .db 0x41 ;;command init
; .db 0x00
; .db 0x00
; .db 0x00
; .db 0x00
; .db 0xf9 ;;CRC
cmd8:
.db 0x48
.db 0x00
.db 0x00
.db 0x01
.db 0xaa
.db 0x87
acmd41:
.db 0x69
.db 0x40
.db 0xff
.db 0x80
.db 0x00
.db 0xff
cmd58:
.db 0x7a
.db 0x00
.db 0x00
.db 0x00
.db 0x00
.db 0xff
cmd55:
.db 0x77
.db 0x00
.db 0x00
.db 0x00
.db 0x00
.db 0xff
cmd16:
.db 0x50
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
;
;
m_cmd17:
.db 0x51
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
m_cmd24:
.db 0x58
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
.org 0xff00
cmd17:
.db 0x51
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
cmd24:
.db 0x58
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
r7:
.ds 4
:03000000C3000139
:20010000310000CDFE06CD1107214E07CDE0063E3ECDF306CDEA06CDF306FE3FCC4F01FEB3
:2001200064CC4402FE6DCC5A02FE6CCCB101FE6ACC5C01FE69CC8E02FE63CC8601FE61CC9B
:20014000CD02FE0D28C9FE0028C5CD560118C0218807CDE006C93E0DCDF306C93E20CDF3C9
:2001600006CD5006FE00201A3E20CDF3063E79CDF3063E3ACDF306CDEA06FE792004CD56C4
:2001800001E9CD5601C93E20CDF306CD5006FE0020F03E20CDF3063E79CDF3063E3ACDF35A
:2001A00006CDEA06FE7920DACD560111B001D5E9C9CDEB01FEFF2819FE0120F53E0DCDF388
:2001C000063E4FCDF3063E4BCDF3063E0DCDF306C93E0DCDF3063E45CDF3063E52CDF306ED
:2001E0003E52CDF3063E0DCDF306C93E0DCDF3061600CDEA06FE3A2048CD4B06457A805797
:20020000CD5006E5DDE17A858457CD4B067DFE002020CD4B06DD7500DD237D825710F3CDCF
:200220004B067A85FE002019CDEA06FE0A20123E00C9FE01200BCD4B067DFEFF20033E0115
:20024000C93EFFC93E20CDF306CD5006FE002803FDE5E1CD7606E5FDE1C93E20CDF306CDD6
:200260005006FE0028063E0DCDF306C93E20CDF3067ECDA7063E20CDF306E5CD4B06FE00E1
:200280002803E1AFC94DE1713E0DCDF306C93E20CDF306CD4B06FE0028063E0DCDF306C919
:2002A0003E20CDF30606004DED78CDA7063E20CDF306CD4B06FE002802AFC97DED793E0DD8
:2002C000CDF306C9E521F608CDE006E1C9CDEA06FE69CC7E04FE72CCE002FE77CCD003C9C1
:2002E000210509CDE006CD5006FE002805CD5601AFC93A0CFFCB77CA04037C3203FF7D327B
:2003000004FF18087C3202FF7D3203FF212609CDE006CD5006FE002805CD5601AFC9CDC4DC
:2003200002CDEA06FE79C29C05E5CDE3052100FFCD1A06CD0B06FE00203DCD0B06FEFE204A
:20034000F90600E1CD1306772310F90600CD1306772310F9CD1306CD130616FFCD280601C8
:200360000002ED423E0DCDF306CD7F03CDF306CD7F03CDF306AFC9E1214D09CDE006C9C500
:200380000600E5219D08CDE006E17CCDA7067DCDA7063E20CDF306CDF3067E23CDA70678AE
:2003A000FE01282378E60FFE0128073E20CDF30618153E0DCDF3067CCDA7067DCDA7063ECB
:2003C00020CDF306CDF30610D13E0DCDF306C1C9211509CDE006CD5006FE002805CD560191
:2003E000AFC93A0CFFCB77CAF4037C3209FF7D320AFF18087C3208FF7D3209FF213209CD1A
:20040000E006CD5006FE002805CD5601AFC9CDC402CDEA06FE79C29C05E5CDE3052106FF22
:20042000CD1A06CD0B06FE00C2760416FECD2806E106005623CD280610F906005623CD28D0
:200440000610F916FFCD2806CD2806CD0B06E60FFE052023CD0B06FE0028F9CDE3050100B6
:2004600002ED423E0DCDF306CD7F03CDF306CD7F03CDF306AFC9E1215809CDE006C9CD9F4D
:2004800004217409CDE006CDC402CDEA06FE79C29C05CD5601CDBC0421FC08CDE006C90685
:2004A0000621B3091100FF7E12231310FA060621B9091106FF7E12231310FAC9AFCBF7CB9F
:2004C000FFD3880650CDF305AFD388CD0105FE01C2A005CD1D05FE01C2A005CD5705FE01E7
:2004E000C2A005CD7605CDAC053A0CFFCB7FCAA005CB772807216309CDE006C9216A0918AB
:20050000F7218F09CD1A06CD0B06F521D408CDE006F1F5CDA7063E0DCDF306F1C9CDE305DB
:20052000219509CD1A06CD0B06FE01C00604210CFFCD1306772310F921DA08CDE0063E01BE
:20054000CDA706210CFF06047ECDA7062310F93E0DCDF3063E01C9CDE30521A709CD1A063B
:20056000CD0B06F521E008CDE006F1F5CDA7063E0DCDF306F1C9CDE305219B09CD1A06CD8D
:200580000B06FE00F521E708CDE006F1F5CDA7063E0DCDF306F1C8CD570518DACD5601C962
:2005A000213F09CDE006CD5601C30001CDE30521A109CD1A06CD0B06F50604210CFFCD13E1
:2005C00006772310F921EF08CDE006F1F5CDA706210CFF06047ECDA7062310F93E0DCDF3E2
:2005E00006F1C9AFCBF7CBFFD3880608CDF305AFD388C9CBAFD3880000000000000000CB5F
:20060000EFD388000000000010E9C9CD1306FEFF28F9C916FFCD28067BC9E5C5060656CDD4
:2006200028062310F9C1E1C9C50E000608AFCB021FCBAFD388000000000000CBEFD388DBB4
:20064000880FCB1310E7AFD388C1C9C506021803C50604210000180429292929CDEA06CD78
:20066000F306CDBA06FEFF2809E60FB56F10E9C1AFC93EFFC1C93E0DCDF306E5219D08CD2B
:20068000E006E17CCDA7067DCDA7063E20CDF306CDF30606107E23CDA7063E20CDF3061057
:2006A000F43E0DCDF306C9F50F0F0F0FCDD406CDF306F1CDD406CDF306C9D6303813FE0A4E
:2006C000380ED611FE063806D620FE063003C60AC93EFFC9E60FFE0A3803C637C9C630C922
:2006E0007EFE00C8CDF3062318F6DB85CB4728FADB84C9F5DB85CB5728FAF1D384C9060B48
:200700000E87214307EDB306090E85213A07EDB3C93E00D3893ECFD3893E0FD3893E07D308
:20072000893EFFD3893E00D38B3ECFD38B3EFFD38B3E07D38B3EFFD38BC918144403C105B5
:20074000681100180200144403C1056811004D6F6E69746F72205A38302B53494F2B5049C8
:200760004F20766572302E37312853504929202062792050696E65636F6E6520323032306A
:200780002F30392F32370D000D3F202048656C700D6420206D656D6F72792064756D700DDA
:2007A0006D20206D656D6F7279206368616E676520202061646472657373206F6C64206E3A
:2007C00065770D6C20206865782066696C65206C6F61640D6A20206A756D700D692020692D
:2007E0002F6F20726567697374657220202020692F6F2D61646472657373206F6C64206E4F
:2008000065770D63202063616C6C0D6169207370692873642D636172642920496E69746961
:20082000616C697A6174696F6E0D6172207370692873642D636172642920726561642020B6
:2008400028353132627974652F626C6F636B2920203078303030302D307866666666207319
:2008600065740D6177207370692873642D63617264292077726974652028353132627974E5
:20088000652F626C6F636B2920203078303030302D307866666666207365740D00616464D9
:2008A0007220202B30202B31202B32202B33202B34202B35202B36202B37202B38202B39AB
:2008C000202B41202B42202B43202B44202B45202B460D00434D44303A00434D44383A0030
:2008E000434D4435353A0041434D4434313A00434D4435383A00205965733A004F4B0D001F
:200900004552520D00207265616420626C6F636B204E6F3A0020777269746520626C6F63D8
:200920006B204E6F3A00207361766520616464723A0020777269746520616464723A0053DE
:20094000706920496E6974204572720D00636D643137204572720D00636D64323420457251
:20096000720D003A534448430D003A534420566572320D00207370692873642D6361726400
:200980002920496E697469616C697A65203A0040000000009548000001AA876940FF80002B
:1F09A000FF7A00000000FF7700000000FF5000000200FF5100000200FF5800000200FF4E
:0CFF00005100000200FF5800000200FF4A
:00000001FF