石原 博の覚書

電子工作に関する日々の覚書を記載します

avrcpm注意点5-3

2020-10-31 20:56:43 | 日記

avrcpm注意点5-2の最後に zexdocのテストのうち
cpd, cpiでエラーが出ていることを報告したが、
これはavrcpmが原因でないことが分かった。

原因は思いもよらないところ。以下に状況を説明する。
[1]zexdocで <inc,dec>(<ix,iy>+1)が異常終了することがわかった
[2]全テストをすると12時間以上かかることから、zexdocのソースを編集し一部のテストだけ実行するように変更しアセンブルすることを試みた
[3]ソースにはマクロが使われており、またz80のニーモニックのためcp/mのasm.comではアセンブル出来ない。zmacアセンブラが必要らしい。しかしzmacの入手方法がわからない。
[4]やむおえず、rubyを使用してマクロ展開。linux上のz80asmを使用してアセンブル
[5]これで調査し、異常終了は解決出来た(avrcpm注意点5-2 参照) ところが、cpd, cpiでエラーが発生することがわかった

原因
zexdocのソースは以下のとおり
----------------
; cpd<r> (1) (6144 cycles)
cpd1: db 0d7h  ; flag mask
 tstr 0edh,0a9h,0,0,0c7b6h,072b4h,018f6h,msbt+17,08dbdh,1,0c0h,030h,094a3h
 tstr 0,010h,0,0,0,0,0,0,0,010,0,-1,0  ; (1024 cycles)
 tstr 0,0,0,0,0,0,0,0,0,0,0d7h,0,0  ; (6 cycles)
 db 0a8h,07eh,06ch,0fah   ; expected crc
 tmsg 'cpd<r>........................'

; cpi<r> (1) (6144 cycles)
cpi1: db 0d7h  ; flag mask
 tstr 0edh,0a1h,0,0,04d48h,0af4ah,0906bh,msbt,04e71h,1,093h,06ah,0907ch
 tstr 0,010h,0,0,0,0,0,0,0,010,0,-1,0  ; (1024 cycles)
 tstr 0,0,0,0,0,0,0,0,0,0,0d7h,0,0  ; (6 cycles)
 db 006h,0deh,0b3h,056h   ; expected crc
 tmsg 'cpi<r>........................'

rubyでマクロを展開したものは以下のとおり
---------------------
; cpd<r> (1) (6144 cycles)
cpd1: db 0d7h  ; flag mask
lab41: db 0edh,0a9h,0,0
 dw 0c7b6h,072b4h,018f6h,msbt+17,08dbdh,1
 db 0c0h
 db 030h
 dw 094a3h
lab42: db 0,010h,0,0
 dw 0,0,0,0,0,010
 db 0
 db -1
 dw 0  ; (1024 cycles)
lab43: db 0,0,0,0
 dw 0,0,0,0,0,0
 db 0d7h
 db 0
 dw 0  ; (6 cycles)
 db 0a8h,07eh,06ch,0fah   ; expected crc
lab44: db 'cpd<r>........................'
 ds lab44+30-$,'.'
 db '$'

; cpi<r> (1) (6144 cycles)
cpi1: db 0d7h  ; flag mask
lab45: db 0edh,0a1h,0,0
 dw 04d48h,0af4ah,0906bh,msbt,04e71h,1
 db 093h
 db 06ah
 dw 0907ch
lab46: db 0,010h,0,0
 dw 0,0,0,0,0,010
 db 0
 db -1
 dw 0  ; (1024 cycles)
lab47: db 0,0,0,0
 dw 0,0,0,0,0,0
 db 0d7h
 db 0
 dw 0  ; (6 cycles)
 db 006h,0deh,0b3h,056h   ; expected crc
lab48: db 'cpi<r>........................'
 ds lab48+30-$,'.'
 db '$'

ここで注意が必要なのは、以下の部分の「010」。

ただしソースがおかしいわけでも、マクロの展開がおかしいわけでもない。
------------------------------------
lab42: db 0,010h,0,0
 dw 0,0,0,0,0,010

lab46: db 0,010h,0,0
 dw 0,0,0,0,0,010

実は z80asm では 「010」は(unixの伝統か?)8進数として扱われ、
8とアセンブルされてしまうが、オリジナルでは10とアセンブルされている。
(実はオリジナルのzexdoc.comと、z80asmでアセンブルしたzexdoc.comを xxd と diffを使用し比較し気づいた)

結局avrcpmは、前回の修正を行えばzexdocで問題が出ないことがわかった。

 


avrcpm注意点5-2

2020-10-23 17:03:02 | 日記

まず異常終了している<inc,dec> (<ix,iy>+1)を調査

config.inc でINS_DEBUGを有効にすると、以下の情報が得られた

INC (IY+1)
HVNC A =33 BC =5057 DE =8894 HL =2C28 SP=286F PC=1CBE FD 34 01
a'=00 bc'=0000 de'=0000 hl'=0000 IX=0102 IY=0102 I=00
C A =33 BC =5057 DE =8894 HL =2C28 SP=286F PC=1CC1 01 ED 73 -->本来は 00 ED 73
a'=00 bc'=0000 de'=0000 hl'=0000 IX=0102 IY=0102 I=00
C A =33 BC =73ED DE =8894 HL =2C28 SP=286F PC=1CC4 07 1D 31

DEC (IX+1)
HVNC A =33 BC =5057 DE =8894 HL =2C28 SP=286F PC=1CBE DD 35 01
a'=00 bc'=0000 de'=0000 hl'=0000 IX=0102 IY=0102 I=00
S H NC A =33 BC =5057 DE =8894 HL =2C28 SP=286F PC=1CC1 FF ED 73 -->本来は 00 ED 73
a'=00 bc'=0000 de'=0000 hl'=0000 IX=0102 IY=0102 I=00

どうもIY+1やIX+1が 0x1CC1のアドレスを指しており、もともと00だったものが、01やFFになっている。
FFとなってしまった場合に、その部分を RST 7 と解釈して異常を起こしている

インストラクションを実行しているのはZ80int-jmp.asmのこの部分。
instr fetch_MXX, op_INC, store_MXX_0 ;34 ;INC (xx+d)
instr fetch_MXX, op_DEC, store_MXX_0 ;35 ;DEC (xx+d)

fetchとstoreは以下の部分なので、mem_read_dsが怪しい。
fetch_MMX
------------
do_fetch_mxx:
sbic flags,prefixfd
rjmp fetchmxx_fd
ldd xh,y+oz_xh
ldd xl,y+oz_xl
rjmp fetchmxx1
fetchmxx_fd:
ldd xh,y+oz_yh
ldd xl,y+oz_yl
fetchmxx1:
mem_read_ds opl, z_pc ;get displacement
adiw z_pcl,1
clr oph ;sign extend
tst opl
brpl fetchmxx2
com oph
fetchmxx2:
add xl,opl ;add displacement
adc xh,oph
mem_read_d opl ;get operand
ret ;(Ix+d) still in xl,xh

store_MXX_0
--------------
do_store_mxx_0:
mem_write_s opl ;store operand
ret


dram-4bit.inc内のmem_read_dsを見ると、xh, xlを壊していた。
mem_read_ds opl, z_pc なので、xh, xl は DEC (IX+1) DD 35 01 の displacementの部分を指すように
変更される。なので DEC (IX+1)だとdisplacementの次のアドレスをデクリメントしFFになる。
辻褄は完全にあう。
----------------------------------------------
; Read byte from DRAM
; mem_read destreg, memaddr

.macro mem_read_ds
movw xl,@1l
lcall dram_read
mov @0,temp
.endm

ちなみに dram-8bit.incでは xh, xlは壊さない
---------------------------------
.macro mem_read_ds
; cli ;1
out PORTD,@1h ;1
out PORTC,_RAS0 ;1
out PORTD,@1l ;1
out PORTC,_CAS0 ;1
out DDRD,_0 ;1
out PORTC,_OE ;1
rjmp PC+1 ;2
dram_wait DRAM_WAITSTATES ;
in @0,PIND ;1
out PORTC,_255 ;1
; sei ;1
out DDRD,_255 ;1 = 14 + DRAM_WAITSTATES
.endm

4bit DRAMでのテストはしてなかったのだろうと思われる。
結局 mem_read_ds で xh, xlを保存するようにして回避
-------------------------------
.macro mem_read_ds
push xh
push xl
movw xl,@1l
lcall dram_read
pop xl
pop xh
mov @0,temp
.endm

同様のことが mem_read_sにもあり、push popした
----------------------------------------------
.macro mem_read_s
push xh
push xl
movw xl,@0l
lcall dram_read
pop xl
pop xh
.endm

以上の修正でturbo pascalが動くようになった。

 

ただまだエラーが...

Z80doc instruction exerciser
<adc,sbc> hl,<bc,de,hl,sp>....  OK
add hl,<bc,de,hl,sp>..........  OK
add ix,<bc,de,ix,sp>..........  OK
add iy,<bc,de,iy,sp>..........  OK
aluop a,nn....................  OK
aluop a,<b,c,d,e,h,l,(hl),a>..  OK
aluop a,<ixh,ixl,iyh,iyl>.....  OK
aluop a,(<ix,iy>+1)...........  OK
bit n,(<ix,iy>+1).............  OK
bit n,<b,c,d,e,h,l,(hl),a>....  OK
cpd<r>........................  ERROR **** crc expected:a87e6cfa found:7f0bf9d2
cpi<r>........................  ERROR **** crc expected:06deb356 found:0855bd37
<daa,cpl,scf,ccf>.............  OK
<inc,dec> a...................  OK
<inc,dec> b...................  OK
<inc,dec> bc..................  OK
<inc,dec> c...................  OK
<inc,dec> d...................  OK
<inc,dec> de..................  OK
<inc,dec> e...................  OK
<inc,dec> h...................  OK
<inc,dec> hl..................  OK
<inc,dec> ix..................  OK
<inc,dec> iy..................  OK
<inc,dec> l...................  OK
<inc,dec> (hl)................  OK
<inc,dec> sp..................  OK
<inc,dec> (<ix,iy>+1).........  OK
<inc,dec> ixh.................  OK
<inc,dec> ixl.................  OK
<inc,dec> iyh.................  OK
<inc,dec> iyl.................  OK
ld <bc,de>,(nnnn).............  OK
ld hl,(nnnn)..................  OK
ld sp,(nnnn)..................  OK
ld <ix,iy>,(nnnn).............  OK
ld (nnnn),<bc,de>.............  OK
ld (nnnn),hl..................  OK
ld (nnnn),sp..................  OK
ld (nnnn),<ix,iy>.............  OK
ld <bc,de,hl,sp>,nnnn.........  OK
ld <ix,iy>,nnnn...............  OK
ld a,<(bc),(de)>..............  OK
ld <b,c,d,e,h,l,(hl),a>,nn....  OK
ld (<ix,iy>+1),nn.............  OK
ld <b,c,d,e>,(<ix,iy>+1)......  OK
ld <h,l>,(<ix,iy>+1)..........  OK
ld a,(<ix,iy>+1)..............  OK
ld <ixh,ixl,iyh,iyl>,nn.......  OK
ld <bcdehla>,<bcdehla>........  OK
ld <bcdexya>,<bcdexya>........  OK
ld a,(nnnn) / ld (nnnn),a.....  OK
ldd<r> (1)....................  OK
ldd<r> (2)....................  OK
ldi<r> (1)....................  OK
ldi<r> (2)....................  OK
neg...........................  OK
<rrd,rld>.....................  OK
<rlca,rrca,rla,rra>...........  OK
shf/rot (<ix,iy>+1)...........  OK
shf/rot <b,c,d,e,h,l,(hl),a>..  OK
<set,res> n,<bcdehl(hl)a>.....  OK
<set,res> n,(<ix,iy>+1).......  OK
ld (<ix,iy>+1),<b,c,d,e>......  OK
ld (<ix,iy>+1),<h,l>..........  OK
ld (<ix,iy>+1),a..............  OK
ld (<bc,de>),a................  OK
Tests complete

 


avrcpm注意点5-1

2020-10-23 16:58:18 | 日記

CP/Mでいくつかのプログラムが動くようになりました。

しかし昔なつかしいturbo pascalが動きません。
どうも完全にはZ80コンパチではないようです。

http://mdfs.net/Software/Z80/Exerciser/CPM.zipから ZEXDOC.COMを利用しチェックしたところ、以下のエラーが発生

G>zexdoc

Z80doc instruction exerciser
<adc,sbc> hl,<bc,de,hl,sp>.... OK
add hl,<bc,de,hl,sp>.......... OK
add ix,<bc,de,ix,sp>.......... OK
add iy,<bc,de,iy,sp>.......... OK
aluop a,nn.................... OK
aluop a,<b,c,d,e,h,l,(hl),a>.. OK
aluop a,<ixh,ixl,iyh,iyl>..... OK
aluop a,(<ix,iy>+1)........... ERROR **** crc expected:e849676e found:160f45a1
bit n,(<ix,iy>+1)............. ERROR **** crc expected:a8ee0867 found:a9e32ca1
bit n,<b,c,d,e,h,l,(hl),a>.... OK
cpd........................ OK
cpi........................ OK
<daa,cpl,scf,ccf>............. OK
<inc,dec> a................... OK
<inc,dec> b................... OK
<inc,dec> bc.................. OK
<inc,dec> c................... OK
<inc,dec> d................... OK
<inc,dec> de.................. OK
<inc,dec> e................... OK
<inc,dec> h................... OK
<inc,dec> hl.................. OK
<inc,dec> ix.................. OK
<inc,dec> iy.................. OK
<inc,dec> l................... OK
<inc,dec> (hl)................ OK
<inc,dec> sp.................. OK
<inc,dec> (<ix,iy>+1).........Z80doc instruction exerciser
<adc,sbc> hl,<bc,de,hl,sp>.... ERROR **** crc expected:f8b4eaa9 found:2c0c7bee
add hl,<bc,de,hl,sp>.......... ERROR **** crc expected:89fdb635 found:fbf631b4
add ix,<bc,de,ix,sp>.......... ERROR **** crc expected:c133790b found:7a22348f

CRCエラーがいくつかあるし、途中<inc,dec> (<ix,iy>+1)でエラー起こして最初から動き出している。
どうも<ix,iy>+1が怪しい。 

ただし実行に12時間程度かかってしまう。デバッグで何度も実行することを考えると正常に終了しているテストはスキップしたい。そこでZEXDOC.ASMで正常終了のテストをコメントアウトすることを考えた。
ソースを自前でアセンブルしたいが、マクロを大量に使っており、簡単にはアセンブル出来ない。

そこでrubyを使ってmacroを展開し、、linux上のz80asmでアセンブル出来るようにした。


avrcpm注意点4

2020-10-18 13:38:31 | 日記
CP/Mディスク作成

https://github.com/petersieg/avrcpm を参考にさせて頂いてます。

付属するCPMDSK_A_IMGでは動作します。

しかしサイトから The Unofficial CP/M Web site(http://www.cpm.z80.de/)等から
ソフトを入れたいと考えました。

neko javaさんの、「CP/Mディスクイメージ作成手順メモ」を参考に、
64セクタ/トラック、244トラックで作成を考えました。ところが上手く動きません。

通常はbios内だけにディスクパラメタがあるのですが、
実は、dsk_fsys.asm内にもあります。これも修正が必要です。(当然BIOSも修正が必要)

1トラック=64セクタ中 IPL=1セクタ、CCP+BDOS=44セクタとして、残り19セクタまでBIOSに割り当てることが可能なため、
offsetは1としています。

さらに同じようにdiskdefsを作成し mkfs.cpm を使用してディスクイメージを作成することが必要です。

この状態で、通常のコマンドやMBASICの単純な動作確認は通ります。しかしBDS Cでコンパイルの実験をすると、
bad sectorエラーが出ます。SDRAMのノイズ等のハードも疑ったのですが、思ってもみないところで問題がありました。

===ディスクイメージ作成スクリプト(失敗)===
dd conv=sync bs=128 count=1 if=ipl.bin > cpm.bin
dd conv=sync bs=128 count=44 if=cpm.sys >> cpm.bin
dd conv=sync bs=128 count=17 if=bios.bin >> cpm.bin

mkfs.cpm -f CPM-A -b cpm.bin -L drive_a diskimage
cpmcp -f CPM-A diskimage ./temp/A/*.* 0:
mv diskimage CPMDSK_A.IMG
=======================================

これで作成したイメージは、mkfs.cpmだけだと16,384バイト、cpmcpを行うと243,712バイト(イメージ内にコピーするデータによる)
これをパーティションを切った上でfat16でフォーマットしたSDRAMにコピーするのですが、
avrcpm側ではこの領域を広げることが出来ないようです。
そもそも 128byte/sec 64sec/trk 244trk なら 1,998,848バイトです。

mkfsのソースは読んでませんが、予め領域を確保していれば良いことが分かりました。そこで

===ディスクイメージ作成スクリプト(失敗)===
dd conv=sync bs=128 count=1 if=ipl.bin > cpm.bin
dd conv=sync bs=128 count=44 if=cpm.sys >> cpm.bin
dd conv=sync bs=128 count=17 if=bios.bin >> cpm.bin

dd conv=sync bs=8192 count=244 if=/dev/zero > diskimage
mkfs.cpm -f CPM-A -b cpm.bin -L drive_a diskimage
cpmcp -f CPM-A diskimage ./temp/A/*.* 0:
mv diskimage CPMDSK_A.IMG
=======================================
としています。

Neko Javaさんのところでは、1つのファイルに複数CP/Mドライブイメージを入れてます。
Dドライブは領域不足になるのではないかなぁ
私の場合は、Aドライブは変更せずCドライブだけ導入ソフトを変更するということがあるので、
ドライブ毎にファイルを分けています。
===Neko Javaさんのページ ディスクイメージ作成===
mkfs.cpm -f cpm_d diskimage
mkfs.cpm -f cpm_c diskimage
mkfs.cpm -f cpm_b diskimage
mkfs.cpm -f cpm_a -b cpm.bin -L test diskimage
=======================================================

様々なサイトにお世話になりながら、やっと動くものが出来ました。

参考
CP/Mディスクイメージ作成手順メモ
https://www.mikrocontroller.net/articles/AVR_CP/M

===dsk_fsys.asm(オリジナル)===
dpbdat_avrcpm: ;(dpb243)
.db 0x00,0x1A ;sector offset, low(spt)
.db 0x00,0x03 ;high (spt), block shift
.db 0x07,0x00 ;bock mask, extent mask
.db 0xF2,0x00 ;disk size - 1,
.db 0x3F,0x00 ;dir max
.db 0xC0,0x00 ;alloc0, alloc1
.db 0x10,0x00 ;chk size
.db 0x02,0x00 ;offset
=======================

===dsk_fsys.asm(修正後)===
dpbdat_avrcpm: ;
.db 0x00,64 ;sector offset, low(spt)
.db 0x00,4 ;high (spt), block shift
.db 15,0x00 ;bock mask, extent mask
.db 0xcb,0x03 ;disk size - 1,
.db 0x7F,0x00 ;dir max
.db 0xC0,0x00 ;alloc0, alloc1
.db 0x20,0x00 ;chk size
.db 0x01,0x00 ;offset
=======================


===BIOS内該当部分========
dpb972:
dw 64 ;sec per track
db 4 ;block shift BSH 2048=128*(2^4)
db 15 ;block mask BLM 2048/128-1=15
db 0 ;extnt mask EXM
dw 971 ;disk size-1 DSM 128*64*(244-1)/2048-1=971
dw 127 ;directory max DRM 2*64-1
db 192 ;alloc0
db 0 ;alloc1
dw 32 ;check size CKS (DRM+1)/4=(127+1)/4=32
dw 1 ;offset
============================

===diskdefs===
# CP/M A:drive
diskdef CPM-A
seclen 128
tracks 244
sectrk 64
blocksize 2048
maxdir 128
skew 1
boottrk 1
os 2.2
end
=================

avrcpm注意点3

2020-10-18 13:37:49 | 日記
デバッグ

https://github.com/petersieg/avrcpm を参考にさせて頂いてます。

config.incでデバックの指定が出来ます。
===config.inc===
;Debugging aids

.equ BOOTWAIT = 1
.equ MEMTEST = 1
.equ MEMFILL = 1 /* Fill DRAM */
.equ SRAM_FILL = 1 /* Fill unused SRAM */
.equ MMC_DEBUG = 0 /* Increase for more debugging */
.equ MMC_DEBUG_RDW = 0
.equ DSKSEL_DEBUG = 0
.equ DISK_DEBUG = 0 /* 1 = BOOT/HOME debug, 2 = +R/W debug */
.equ HOSTRW_DEBUG = 0
.equ FAT16_DEBUG = 0
.equ FAT16_DBG_FAT = 0
.equ HEAP_DEBUG = 0
.equ PORT_DEBUG = 0
.equ INS_DEBUG = 0
.equ STACK_DBG = 0
.equ PRINT_PC = 0
.equ TIMER_DEBUG = 0
.equ I2C_STATE_DEBUG = 0
.equ MEMDUMP_DEBUG = 1

しかしDISK_DEBUGを1にすると、アセンブル時にエラーが発生します。(dsk_fsys.asm(1017): error: Relative branch out of reach
)
相対ブランチが届かないのだとは分かりますが、どこなのかわからない。調べてみると以下の部分で発生していました。
これでデバッグが出来ます。

dskdbg1:
ldd temp,y+o_seekdsk
subi temp,-('A')
- rcall uartputc
+ lcall uartputc
printstring ": trk "
ldd temp2,y+o_seektrk+1
ldd temp,y+o_seektrk