SSブログ
English Version

レトロマイコン86ボードの構想(その8)Cold Start LoaderでのCP/M-86の起動 [8086]

 前回の記事に書いたようにCP/M本体をHexファイル化してHexファイルローダーでロードすることでCP/M-86が起動できたので今回はCP/MのコールドスタートローダーをHexファイルローダーで読込むことでCP/M-86を起動してみます。

 CP/M-86の起動シーケンスは前回も書いたように
  1. Bootstrap
     最初のセクタ(128バイト)から読み込んだBootstrapをV20にのメモリにロードし、起動することで第2セクタ以降に格納されているCold Start Loader(simple version of CP/M-86)をメモリに読込む

  2. Cold Start Loader
     DiskA内のCPM本体(CPM.SYS)をメモリに読込み起動することでCP/M自体が立ち上がる

という流れです。

 Cold Start LoaderはCP/Mのサブセット版なので専用のBIOSが必要になりますが、今回はBIOSをCP/M-86 System Guideに載っているサンプルを参考に作成しているので「loader_bios EQU false」の部分をtrueに変更することでLoader用のBIOSのHexファイルを生成できるようにしています。

 loader_biosのEQU宣言を変更する度にBIOSのソースファイルのタイムスタンプが変わるのが嫌だったのでEQU宣言をPicBois.defファイルに移し、includeするようにしました。
 include化したことで予想外のエラー(ソースにはない内容のエラーを検出)したので確認したところ、CPM86エミュレータはファイルのエンドにCP/MのEOFマークである01AHを渡していない模様で、PicBois.defファイルの末尾に01AHのコードを入れたらエラーは出なくなりました。

 アセンブルした結果、生成されたBIOSのHexファイルをCP/M-86関連のダウンロードファイルに入っているCold Start Loader用のCP/MとBDOSのHexファイルと連結します。
 連結方法としてシステムガイドには

PIP LOADER.H86=LDCPM.H86,LDBDOS.H86,LDBIOS.H86


と書いてあるのですが前回の記事で書いたようにms-dos player+cpm86.exeでのpip起動ではエラーになるのでエディタで連結しました。

 連結したLOADER.H86をgencmdコマンドでコマンドに変換すればCold Start Loaderが完成します。

C:¥picle¥V20¥asm¥bios¥cmd>msdos cpm86 gencmd loader 8080 CODE[A400]
CP/M-86 emulator for DOS vers 1.3 - 11/30/97
Copyright (c) 1985, 1997 Jim Lopushinsky

BYTES READ 1073
RECORDS WRITTEN 2C



C:¥picle¥V20¥asm¥bios¥cmd>


 [A400]のスイッチはセグメントを0400Hにするためです。
 生成されたLOADER.CMDを前回の記事で書いたようにCMDヘッダを削除しHexファイル化します(セグメントの値は0400H)。

 Cold Start Loader用のBIOSのINIT処理のエントリは1200HなのでCold Start LoaderのHexファイルをHexファイルローダで読込み、0400:1200Hから実行するとCP/M-86が起動します。

 Cold Start LoaderをHexファイルローダでロードしてCP/M-86を起動した際のサンプルログを貼っておきます。
 CP/M本体のセグメントアドレスと最終オフセットが表示されていますが、これはCold StartLoaderが表示しているもので、もう少し見栄えを良くしたいのですがソースが無いのでまずはそのままにしておきます。
 Cold Start LoaderのサイズはCP/M本体の半部以下なのでCP/M-86の起動が少し楽になりました。

Cold Start LoaderでのCP/M-86の起動
:¥¥ +B000-BDBA # CP/M-86 boot 2019/08/23 +C000-CC8D #LibCpm CP/M86(PMP) v0.01 2019/08/17 +D000-DEEB #LibSpi SPI lib V0.04 for CP/M86 2019/08/16 +E000-EDC7 # Memory check executer 2019/08/18 +F000-FC43 # Pic24V20 HexLoader v0.02 2019/08/12 :¥<$F000 3139 :run HexLoader Start 2000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000001 :¥< 3514 :run Pic24V20 CP/M-86 Version 2.2 Segment Address = 0040 Last Offset = 31FF System Generated by skyriver 2019/08/23 A>dir A: ASM86 CMD : ASSIGN CMD : CONFIG CMD : CPM SYS A: DATA PFK : DDT86 CMD : DSKMAINT CMD : ED CMD A: FUNCTION CMD : GENCMD CMD : HELP CMD : HELP HLP A: PIP CMD : PRINT CMD : SETUP CMD : STAT CMD A: SUBMIT CMD : TOD CMD A>stat A: RW, Free Space: 1,780k A>stat dsk: A: Drive Characteristics 15,552: 128 Byte Record Capacity 1,944: Kilobyte Drive Capacity 256: 32 Byte Directory Entries 0: Checked Directory Entries 128: 128 Byte Records / Directory Entry 16: 128 Byte Records / Block 64: 128 Byte Records / Track 1: Reserved Tracks A>



★2019/10/22 追記
 Cold Start LoaderのCPM.SYS起動部のソース(LDCPM.A86)を見つけたのでメッセージを下記のように変更しました。

... loading
Pic24V20 ver0.02 CP/M-86 Version 1.1
Segment Address = 0040
    Last Offset = 31FF
  System Generated by skyriver 2019/10/07

A>



[TOP] [ 前へ ] 連載記事 [ 次へ ]


nice!(1)  コメント(0) 
共通テーマ:趣味・カルチャー

レトロマイコン86ボードの構想(その7)HexローダーでのCP/M起動に成功^^ [8086]

 前回の記事で書いたようにPICのゆりかごの中で動作するV20(8088互換)の動作が安定になったのでCP/M-86のBIOSを作成し、CP/M-86の起動に先程、成功しました(^^)/

 CP/M-86の起動は「3チップ構成68Kマイコンの構想(その8)ローダーによるCP/Mの起動」で書いたようなCP/M-68Kの起動シーケンスと同様で

  • Bootstrap
     ROMまたは最初のセクタに格納されている最初に起動されるローダーでOS用にリザーブされたトラック(標準的な8インチディスクなら最初の2トラック)に格納されているCold Start Loaderを読込み起動する

  • Cold Start Loader
     CP/M本体のサブセット版(simple version of CP/M-86)でディスクA内にあるCP/M本体(CPM.SYS)をメモリに読込み起動する

のような起動シーケンスになります。

 今回は「3チップ構成68Kマイコンの構想(その4)CP/M-68K 初ブート」の記事で書いたCP/M-68Kの時と同じようにCP/M本体をHexファイルローダーでV20のメモリ内にロードし、CP/M-86を起動しました。

 起動手順の概要は次のとおりです。

  1. BIOSのアセンブル
     次のコマンドで今回のハード(Pic24V20)用に作成したbiosのソースをアセンブルします。

    C:¥picle¥V20¥asm¥bios¥cmd>msdos cpm86 asm86 picbios
    CP/M-86 emulator for DOS vers 1.3 - 11/30/97
    Copyright (c) 1985, 1997 Jim Lopushinsky

    CP/M 8086 ASSEMBLER VER 1.1
    END OF PASS 1
    END OF PASS 2
    END OF ASSEMBLY. NUMBER OF ERRORS: 0. USE FACTOR: 7%


    C:¥picle¥V20¥asm¥bios¥cmd>

  2. CP/MとbiosのHexファイルの連結
     ダウンロードしたCP/M-86関連ファイルに入っていたCPM.H86の末尾に上のbiosのアセンブルで生成されたBIOSのHexファイルを連結します。
     PIPコマンドで連結してもいいようなのですが、私の環境(ms-dos playerでcpm86.exe経由でpip.cmdを起動)ではうまく連結できなかったので秀丸エディタで連結しました。連結したファイルはCPMX.HEXのファイル名でセーブします。

  3. CPM.SYSの作成
     次のコマンドで上で連結したHexファイルからCPMX.CMDを作成します。CPMX.CMDはCPM.SYSにリネームすればCold Start LoaderからロードされるCP/M本体のファイルになります。

    C:¥picle¥V20¥asm¥bios¥cmd>msdos cpm86 GENCMD CPMX 8080 CODE[A40]
    CP/M-86 emulator for DOS vers 1.3 - 11/30/97
    Copyright (c) 1985, 1997 Jim Lopushinsky

    BYTES READ 2627
    RECORDS WRITTEN 65



    C:¥picle¥V20¥asm¥bios¥cmd>

  4. CMDファイルのヘッダ削除
     CP/M-86のCMDファイルには128バイトのヘッダが付いているのでバイナリエディタを使って最初の128バイトを削除し、CPMX_NH.SYSのファイル名で保存します。

    CPMX.CMDのヘッダ削除

  5. CPM_NH.SYSのHexファイル作成
     バイナリファイルを0040セグメントから始まるhexファイルに変換し、CPM_NH.HEXのファイル名でセーブします。
     hexファイル変換ツールでセグメント指定ができない場合は、先頭のセグメント指定の行として

    :020000020040BC

    を手動で追加します。

  6. CPM_NH.HEXのロードと起動
     作成したHexファイルをHexファイルローダーを使ってV20のメモリにロードし、0040:2500H(BIOSの先頭部)番地から実行するとCP/M-86が起動します。
     下記はHexファイルロードからCP/M-86起動までのログのサンプルです。

    Hexファイルローダーを使ったCP/M-86の起動
    :¥¥ +B000-BDBA # CP/M-86 boot 2019/08/23 +C000-CC8D #LibCpm CP/M86(PMP) v0.01 2019/08/17 +D000-DEEB #LibSpi SPI lib V0.04 for CP/M86 2019/08/16 +E000-EDC7 # Memory check executer 2019/08/18 +F000-FC43 # Pic24V20 HexLoader v0.02 2019/08/12 :¥<$F000 3139 :run HexLoader Start 2000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000001 :¥< 3514 :run System Generated by skyriver 2019/08/14 A>dir A: ASM86 CMD : ASSIGN CMD : CONFIG CMD : CPM SYS A: DATA PFK : DDT86 CMD : DSKMAINT CMD : ED CMD A: FUNCTION CMD : GENCMD CMD : HELP CMD : HELP HLP A: PIP CMD : PRINT CMD : SETUP CMD : STAT CMD A: SUBMIT CMD : TOD CMD A>ddt86 DDT86 1.2 -d 0000:0000 8F 25 40 00 36 08 66 7C 8F 25 40 00 2E 08 66 7C .%@.6.f|.%@...f| 0000:0010 8F 25 40 00 8F 25 40 00 8F 25 40 00 8F 25 40 00 .%@..%@..%@..%@. 0000:0020 8F 25 40 00 8F 25 40 00 8F 25 40 00 8F 25 40 00 .%@..%@..%@..%@. 0000:0030 8F 25 40 00 8F 25 40 00 8F 25 40 00 8F 25 40 00 .%@..%@..%@..%@. 0000:0040 8F 25 40 00 8F 25 40 00 8F 25 40 00 8F 25 40 00 .%@..%@..%@..%@. 0000:0050 8F 25 40 00 8F 25 40 00 8F 25 40 00 8F 25 40 00 .%@..%@..%@..%@. 0000:0060 8F 25 40 00 8F 25 40 00 8F 25 40 00 8F 25 40 00 .%@..%@..%@..%@. 0000:0070 8F 25 40 00 8F 25 40 00 8F 25 40 00 8F 25 40 00 .%@..%@..%@..%@. 0000:0080 8F 25 40 00 8F 25 40 00 8F 25 40 00 8F 25 40 00 .%@..%@..%@..%@. 0000:0090 8F 25 40 00 8F 25 40 00 8F 25 40 00 8F 25 40 00 .%@..%@..%@..%@. 0000:00A0 8F 25 40 00 8F 25 40 00 8F 25 40 00 8F 25 40 00 .%@..%@..%@..%@. 0000:00B0 8F 25 40 00 8F 25 40 00 8F 25 40 00 8F 25 40 00 .%@..%@..%@..%@. -^C A>


[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

レトロマイコン86ボードの構想(その6)メモリチェックプログラムの製作 [8086]

 前回の記事で書いたようにヘキサファイルをV20のメモリ内にダウンロードできるようになったのでプログラムを作って遊んでいます。
 アセンブラはCP/M-86のASM86を使い、アセンブラから出力されるヘキサファイルをhexファイルローダーでV20内のメモリにダウンロードして動かしています。

 環境としてはMS-DOS Player上でCP/M-86エミュレータ(cpm86.exe)を動かし、ASM86.CMDを起動しています。

 しかし、プログラムを作成して動かしてみると、不安定であり、ブレッドボード上の配線のチェックを行ったところ、接続線が1本断線していましたorz
 今回は2度目の配線なのでテスタで線材の導通を確認しながら配線したのですが、最後の方で一部チェックせずに配線した部分で問題が発生していました(手抜きは駄目ですね・・)^^;

 状況は改善したものの例えばダミーのPUSH/POPを追加しただけで動作が変わることがあったり等、微妙に不安定な要素があったので手抜きせずにメモリチェックプログラムを作成して確認してみました。

 理想を言えばメモリ上に変数を置かずにレジスタだけで動作する(CALLも使用しない)方がいいのですが、そこまで不安定ではないのでメモリ上の変数やCALLは許容することにして、アドレスバスやデータバスのエラーはきちんと検出したいので
  • チェック書込みとチェック方法
     チェック対象メモリ全体にチェックデータを書込んだ後に書き込んだデータが読込めるか確認する。

  • 書き込みデータ
     簡易的な乱数(合同法)を使って生成し、書込み開始時に乱数のseedを保存し、チェック開始時に乱数seedを復元する。
    通常の合同法ではrand(n+1) = A x rand(n) + B(A,Bは素数が望ましい、Bは無い場合もある)ですが、LSBが固定されないように「A x rand(n)」の結果の特定ビットが1の場合、Bを加算する。

  • 長期安定確認
     上記の書込みとチェックを繰り返し動かし(乱数のseedは継続利用)、チェック開始時に何回目のチェックかを2バイトヘキサ表示する。

ようにしました。

 プログラム自体は0010:0000からに置き、0030:0000~7FFE:0000をチェック対象にしています(メモリ最後の部分はPICとのI/F用とリセット時のジャンプ命令で使用するのでチェック対象外)。

 結果として、最初は結構すぐにエラーが発生する(例えばチェック1回目で「err 17E0:0000」が発生)状況でしたが、回路の抵抗値の調整等を行い少し安定になりました。
 最終的には、安定化電源で供給していた電圧がブレッドボード上では0.2V程度低かったので、5.0Vにしたところ数十回の連続チェックも通るようになりました^^

★2019/08/30 変更 {
 チェック処理中であることが判るように約1秒毎に'o'を表示するようにしました。
}
メモリチェックプログラム(アセンブラ)
CP/M ASM86 1.1 SOURCE: MEMCHK.A86 Check Memory title 'Check Memory' ;++++++++++++++++++++++++++++++++++++ ; Check Memory for Pic24V20 ; Ver 0.01 2019/08/19 skyriver ;++++++++++++++++++++++++++++++++++++ FFFF true EQU -1 0000 false EQU not true 000D CR EQU 13 000A LF EQU 10 0008 BS EQU ( 'H' - 40H ) 0010 PrgSeg EQU 0010H 0030 StartSeg EQU 0030H 7FFE EndSeg EQU 7FFEH 0FFF MonMask EQU 0FFFH B46D SEED EQU 46189 1D05 MULVAL EQU 7429 81EF ADDVAL EQU 33263 0400 CHKBIT EQU 0400H ; memory assign ; ffde0 ffde:0000 SD buf 512bytes ; fffe0 ffde:0200 work area 16 bytes ; ffff0 ffff:0000 reset jump ; FFDE PWrkSeg EQU 0FFDEH 0200 SdBufSz EQU 512 0000 SdBuf EQU 0 ; SD buffer offset ; function No. 0000 FC_EXIT EQU 0 ; EXIT CP/M 0001 FC_CONST EQU 1 ; CONST 0002 FC_CONIN EQU 2 ; CONIN 0003 FC_CONOUT EQU 3 ; CONOUT 0004 FC_READ EQU 4 ; READ SD Card 0005 FC_WRITE EQU 5 ; WRITE SD Card 0006 FC_PUNCH EQU 6 ; PUNCH 0007 FC_READER EQU 7 ; READER 0200 PicWrk EQU SdBuf + SdBufSz ; Pic I/F work area 0200 FuncNo EQU PicWrk ; RB 1 ; function No 0201 CoData EQU FuncNo + 1 ; RB 1 ; conout data 0202 SdSec EQU CoData + 1 ; RB 4 ; SD block No. 0206 RetVal EQU SdSec + 4 ; RB 2 ; return value 0208 PreSd EQU RetVal + 2 ; RB 4 ; previos SD block No. 020C ChgFlg EQU PreSd + 4 ; RB 1 ; buffer change flag for Blocking/Deblocking 020D BlkCnt EQU ChgFlg + 1 ; RB 1 ; Block first write counter ; *** offset from PicWrk *** 0000 oFuncNo EQU FuncNo - PicWrk 0001 oCoData EQU CoData - PicWrk 0002 oSdSec EQU SdSec - PicWrk 0006 oRetVal EQU RetVal - PicWrk 0008 oPreSd EQU PreSd - PicWrk 000C oChgFlg EQU ChgFlg - PicWrk 000D oBlkCnt EQU BlkCnt - PicWrk 0010 CSEG PrgSeg ORG 0 0000 8CC8 START: MOV AX,CS 0002 8ED0 MOV SS,AX 0004 BC7801 MOV SP,StackBase 0007 B8DEFF MOV AX,PWrkSeg 000A 8EC0 MOV ES,AX 000C BE0002 MOV SI,PicWrk 000F 2EC7064A0100 MOV CS:ChkCnt,0 00 0016 BA0080 MOV DX,8000H 0019 2EC7064C016D MOV CS:RndVal,SEED B4 0020 BB2C01 MOV BX,offset StMsg 0023 E85100 0077 CALL PutStr 0026 B05B MA010: MOV AL,'[' 0028 E82000 004B CALL PutChar 002B 2EA14A01 MOV AX,CS:ChkCnt 002F 40 INC AX 0030 2EA34A01 MOV CS:ChkCnt,AX 0034 E81E00 0055 CALL PutHexW 0037 B05D MOV AL,']' 0039 E80F00 004B CALL PutChar 003C E86100 00A0 CALL Write 003F E88D00 00CF CALL Check 0042 EBE2 0026 JMPS MA010 ; exit 0044 26C60400 Exit: MOV ES:BYTE PTR oFuncNo[SI],FC_EXIT 0048 EE OUT DX,AL 0049 EBFE 0049 JMPS $ ; PutChar ; AL <- data PutChar: 004B 26C60403 MOV ES:BYTE PTR oFuncNo[SI],FC_CONOUT 004F 26884401 MOV ES:BYTE PTR oCoData[SI],AL 0053 EE OUT DX,AL 0054 C3 Return: RET ; put hex(Word) ; AX <- data PutHexW: 0055 86C4 XCHG AL,AH 0057 E80200 005C CALL PutHex 005A 86C4 XCHG AL,AH ; go through PutHex ; Put Hex(Byte) ; AL <- data 005C 8AD0 PutHex: MOV DL,AL 005E D0E8 SHR AL,1 0060 D0E8 SHR AL,1 0062 D0E8 SHR AL,1 0064 D0E8 SHR AL,1 0066 E80200 006B CALL PutNbl 0069 8AC2 MOV AL,DL ; go through PutNbl ; put nible ; AL <- data 006B 240F PutNbl: AND AL,0FH 006D 0430 ADD AL,'0' 006F 3C3A CMP AL,'9'+1 0071 7202 0075 JC PutN10 0073 0407 ADD AL,'A' - '0' - 10 0075 EBD4 004B PutN10: JMPS PutChar ; put string ; BX <- string(segment:CS) 0077 2E8A870000 PutStr: MOV AL,CS:[BX] 007C 84C0 TEST AL,AL 007E 74D4 0054 JZ Return 0080 E8C8FF 004B CALL PutChar 0083 43 INC BX 0084 EBF1 0077 JMPS PutStr ; rand ; AX -> rand 0086 53 Rand: PUSH BX 0087 52 PUSH DX ; destroyed by mul 0088 2EA14C01 MOV AX,CS:RndVal 008C BB051D MOV BX,MULVAL 008F F7E3 MUL BX 0091 A90004 TEST AX,CHKBIT 0094 7403 0099 JZ Rand10 0096 05EF81 ADD AX,ADDVAL 0099 2EA34C01 Rand10: MOV CS:RndVal,AX 009D 5A POP DX 009E 5B POP BX 009F C3 RET ; write memoy 00A0 2EA14C01 Write: MOV AX,CS:RndVal 00A4 2EA34E01 MOV CS:SeedVal,AX 00A8 BB3000 MOV BX,StartSeg 00AB 8EDB Wri10: MOV DS,BX 00AD BF0000 MOV DI,0 00B0 B90800 MOV CX,8 00B3 E8D0FF 0086 Wri20: CALL Rand 00B6 8905 MOV WORD PTR [DI],AX 00B8 47 INC DI 00B9 47 INC DI 00BA E2F7 00B3 LOOP Wri20 00BC F7C3FF0F TEST BX,MonMask 00C0 7505 00C7 JNZ Wri30 00C2 B06F MOV AL,'o' 00C4 E884FF 004B CALL PutChar 00C7 43 Wri30: INC BX 00C8 81FBFE7F CMP BX,EndSeg 00CC 75DD 00AB JNZ Wri10 00CE C3 RET ; check memory 00CF 2EA14E01 Check: MOV AX,CS:SeedVal 00D3 2EA34C01 MOV CS:RndVal,AX 00D7 BB3000 MOV BX,StartSeg 00DA B80100 MOV AX,1 00DD F8 CLC 00DE 8EDB Chk10: MOV DS,BX 00E0 BF0000 MOV DI,0 00E3 B90800 MOV CX,8 00E6 E89DFF 0086 Chk20: CALL Rand 00E9 3B05 CMP AX,WORD PTR [DI] 00EB 7521 010E JNZ ChkErr 00ED 47 INC DI 00EE 47 INC DI 00EF E2F5 00E6 LOOP Chk20 00F1 F7C3FF0F TEST BX,MonMask 00F5 750F 0106 JNZ Chk30 00F7 B008 MOV AL,BS 00F9 E84FFF 004B CALL PutChar 00FC B020 MOV AL,' ' 00FE E84AFF 004B CALL PutChar 0101 B008 MOV AL,BS 0103 E845FF 004B CALL PutChar 0106 43 Chk30: INC BX 0107 81FBFE7F CMP BX,EndSeg 010B 75D1 00DE JNZ Chk10 010D C3 RET 010E BB4301 ChkErr: MOV BX,offset ErrMsg 0111 E863FF 0077 CALL PutStr 0114 8CD8 MOV AX,DS 0116 E83CFF 0055 CALL PutHexW 0119 B03A MOV AL,':' 011B E82DFF 004B CALL PutChar 011E 8BC7 MOV AX,DI 0120 E832FF 0055 CALL PutHexW 0123 BB4001 MOV BX,offset CrLfMsg 0126 E84EFF 0077 CALL PutStr 0129 E918FF 0044 JMP Exit 012C 0D0A53746172 StMsg DB CR,LF,'Start Memory Check' 74204D656D6F 727920436865 636B 0140 0D0A00 CrLfMsg DB CR,LF,0 0143 0D0A65727220 ErrMsg DB CR,LF,'err ',0 00 ;EnMsg DB CR,LF,'complete',0 014A ChkCnt RW 1 014C RndVal RW 1 014E SeedVal RW 1 0150 RW 20 0178 StackBase EQU ( offset $ + 1 ) AND 0FFFEH END END OF ASSEMBLY. NUMBER OF ERRORS: 0. USE FACTOR: 2%


 アセンブル時のコマンドはこんな感じです。

C:¥picle¥V20¥asm¥bios¥cmd>msdos cpm86 asm86 Memchk
CP/M-86 emulator for DOS vers 1.3 - 11/30/97
Copyright (c) 1985, 1997 Jim Lopushinsky

CP/M 8086 ASSEMBLER VER 1.1
END OF PASS 1
END OF PASS 2
END OF ASSEMBLY. NUMBER OF ERRORS: 0. USE FACTOR: 2%


C:¥picle¥V20¥asm¥bios¥cmd>


 アセンブルした結果、生成されたHexファイルをHexファイルローダーでダウンロードしている様子が下記です。
 Hexファイルの内容をTeraTermにコピペするとデータタイプを表示しながらV20のメモリにロードされます。

:¥¥

+E000-EDC7 # Memory chack executer 2019/08/19
+F000-FC43 # Pic24V20 HexLoader v0.02 2019/08/12

:¥<$F000
3139
:run
HexLoader Start
e3aaaaaaaaaaaaa1
:


 安定化した後の確認結果も貼っておきます。
 尚、途中でリセットして中断していますが、リセットしなければ永遠とメモリチェックを繰り返します。

メモリチェック結果
:l 1:# Memory check executer 2019/08/19 2:# ver 0.01 by skyriver 3: 4:use LibCpm; 5:use LibSpi; 6: 7:var ProgWrk,_WrkVal,_PicDma,SdSec; 8:var EscFlg,EscY; 9: 10: 11:proc PicSrv() { 12: var i,fno,rval; 13: 14: while (1) { 15: while (LATA[-1]&1) {} # wait reset 16: while (LATC[-1]&$40) {} # wait ready off 17: CMCON[0] = CMCON[0]&$feff; # CMP1 off 18: PmpOn(); 19: PmpSetAdr(ProgWrk); 20: fno=MemRd(); # dummy 21: for (i=0;i<2;i=i+1) { 22: _WrkVal[i]=MemRd(); 23: } 24: fno=_WrkVal[0]; # function No 25: rval=0; 26: if (fno=3) { # CONOUT 27: PrnChar_( _WrkVal[1] ); 28: } 29: else if (fno=0) { 30: break; 31: } else { 32: PrnStr_("\nFunc err"); 33: PrnHexB_(fno); 34: } 35: PmpOff(); 36: BusRelease(); 37: CMCON[0] = CMCON[0]|$0100; # CMP1 on 38: } 39:} 40: 41: 42:proc main() { 43: init(); 44: initPmp(); 45: initSpi(); 46: initSd(); 47: 48: ProgWrk = $ffe0; # work addr(fffe0) 49: _PicDma = $fde0; 50: 51: _WrkVal = Alloc(5); 52: SdSec=_WrkVal+2; # long SdSectorNo 53: 54: LATA[0]=LATA[0]|1; # on reset:a0 55: BusReq(); 56: LATA[0]=LATA[0]&$fffe; # off reset:a0 57: 58: PmpOn(); 59: 60: PmpSetAdr($07f0); 61: MemWr($ea);MemWr($00);MemWr($00);MemWr($10);MemWr($00); 62: 63: PmpOff(); 64: LATA[0]=LATA[0]|1; # on reset:a0 65: BusRelease(); 66: 67: Timer_ = 1; 68: while ( Timer_ ); 69: LATA[0]=LATA[0]&$fffe; # off reset:a0 70: 71: while ((LATC[-1]&$40)=0); # wait ready on 72: 73: PicSrv(); 74: 75: BusReq(); 76: PrnStr_("** end **"); 77: 78: Rdump($0100); 79:} :run Start Memory Check [0001][0002][0003][0004][0005][0006][0007][0008][0009][000A][000B][000C][000D][000E][000F][0010][0011][0012][0013][0014][0015][0016][0017][0018][0019][001A][001B][001C][001D][001E][001F][0020][0021][0022][0023][0024][0025][0026][0027][0028][0029][002A][002B][002C][002D][002E][002F][0030][0031][0032][0033]


★2020/09/17 追記
 アセンブラプログラムのコードを内包した一発起動のpicleソースを追記します。

メモリチェックソース(picle)
# Memory check 2020/09/01 # ver 0.02 by skyriver use LibCpm; use LibSpi; var ProgWrk,_WrkVal,_PicDma,SdSec; var EscFlg,EscY; proc m( data ) { MemWr( data ); } proc PicSrv() { var i,fno,rval; while (1) { while (LATA[-1]&1) {} # wait reset while (LATC[-1]&$40) {} # wait ready off CMCON[0] = CMCON[0]&$feff; # CMP1 off PmpOn(); PmpSetAdr(ProgWrk); fno=MemRd(); # dummy for (i=0;i<2;i=i+1) { _WrkVal[i]=MemRd(); } fno=_WrkVal[0]; # function No rval=0; if (fno=3) { # CONOUT PrnChar_( _WrkVal[1] ); } else if (fno=0) { break; } else { PrnStr_("\nFunc err"); PrnHexB_(fno); } PmpOff(); BusRelease(); CMCON[0] = CMCON[0]|$0100; # CMP1 on } } proc main() { init(); initPmp(); # initSpi(); # initSd(); ProgWrk = $ffe0; # work addr(fffe0) _PicDma = $fde0; _WrkVal = Alloc(5); SdSec=_WrkVal+2; # long SdSectorNo LATA[0]=LATA[0]|1; # on reset:a0 BusReq(); LATA[0]=LATA[0]&$fffe; # off reset:a0 PmpOn(); PmpSetAdr($07f0); m($ea);m($00);m($00);m($10);m($00); PmpSetAdr($0100); m($8c);m($c8);m($8e);m($d0);m($bc);m($78);m($01);m($b8); m($de);m($ff);m($8e);m($c0);m($be);m($00);m($02);m($2e); m($c7);m($06);m($4a);m($01);m($00);m($00);m($ba);m($00); m($80);m($2e);m($c7);m($06);m($4c);m($01);m($6d);m($b4); m($bb);m($2c);m($01);m($e8);m($51);m($00);m($b0);m($5b); m($e8);m($20);m($00);m($2e);m($a1);m($4a);m($01);m($40); m($2e);m($a3);m($4a);m($01);m($e8);m($1e);m($00);m($b0); m($5d);m($e8);m($0f);m($00);m($e8);m($61);m($00);m($e8); m($8d);m($00);m($eb);m($e2);m($26);m($c6);m($04);m($00); m($ee);m($eb);m($fe);m($26);m($c6);m($04);m($03);m($26); m($88);m($44);m($01);m($ee);m($c3);m($86);m($c4);m($e8); m($02);m($00);m($86);m($c4);m($8a);m($d0);m($d0);m($e8); m($d0);m($e8);m($d0);m($e8);m($d0);m($e8);m($e8);m($02); m($00);m($8a);m($c2);m($24);m($0f);m($04);m($30);m($3c); m($3a);m($72);m($02);m($04);m($07);m($eb);m($d4);m($2e); m($8a);m($87);m($00);m($00);m($84);m($c0);m($74);m($d4); m($e8);m($c8);m($ff);m($43);m($eb);m($f1);m($53);m($52); m($2e);m($a1);m($4c);m($01);m($bb);m($05);m($1d);m($f7); m($e3);m($a9);m($00);m($04);m($74);m($03);m($05);m($ef); m($81);m($2e);m($a3);m($4c);m($01);m($5a);m($5b);m($c3); m($2e);m($a1);m($4c);m($01);m($2e);m($a3);m($4e);m($01); m($bb);m($30);m($00);m($8e);m($db);m($bf);m($00);m($00); m($b9);m($08);m($00);m($e8);m($d0);m($ff);m($89);m($05); m($47);m($47);m($e2);m($f7);m($f7);m($c3);m($ff);m($0f); m($75);m($05);m($b0);m($6f);m($e8);m($84);m($ff);m($43); m($81);m($fb);m($fe);m($7f);m($75);m($dd);m($c3);m($2e); m($a1);m($4e);m($01);m($2e);m($a3);m($4c);m($01);m($bb); m($30);m($00);m($b8);m($01);m($00);m($f8);m($8e);m($db); m($bf);m($00);m($00);m($b9);m($08);m($00);m($e8);m($9d); m($ff);m($3b);m($05);m($75);m($21);m($47);m($47);m($e2); m($f5);m($f7);m($c3);m($ff);m($0f);m($75);m($0f);m($b0); m($08);m($e8);m($4f);m($ff);m($b0);m($20);m($e8);m($4a); m($ff);m($b0);m($08);m($e8);m($45);m($ff);m($43);m($81); m($fb);m($fe);m($7f);m($75);m($d1);m($c3);m($bb);m($43); m($01);m($e8);m($63);m($ff);m($8c);m($d8);m($e8);m($3c); m($ff);m($b0);m($3a);m($e8);m($2d);m($ff);m($8b);m($c7); m($e8);m($32);m($ff);m($bb);m($40);m($01);m($e8);m($4e); m($ff);m($e9);m($18);m($ff);m($0d);m($0a);m($53);m($74); m($61);m($72);m($74);m($20);m($4d);m($65);m($6d);m($6f); m($72);m($79);m($20);m($43);m($68);m($65);m($63);m($6b); m($0d);m($0a);m($00);m($0d);m($0a);m($65);m($72);m($72); m($20);m($00); PmpOff(); LATA[0]=LATA[0]|1; # on reset:a0 BusRelease(); Timer_ = 1; while ( Timer_ ); LATA[0]=LATA[0]&$fffe; # off reset:a0 while ((LATC[-1]&$40)=0); # wait ready on PicSrv(); BusReq(); PrnStr_("** end **"); Rdump($0100); }



[TOP] [ 前へ ] 連載記事 [ 次へ ]
nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

レトロマイコン86ボードの構想(その5)HEXファイルローダーの製作 [8086]

 前回の記事で書いたように8088互換のV20とPICとのインターフェース部の動作確認が出来たので、今回はインテルヘキサファイルのローダーの製作について書いてみます。

 インテルヘキサファイルのフォーマットに関してはネット上に色々あります(例えばIntel HEX)ので情報は豊富です。
 レコードタイプは
  • 00 : data record(CP/M-86独自の81H~84Hも含む)
  • 01 : end of file
  • 02 : segment(CP/M-86独自の85H~88Hも含む)
  • 03 : start address

に対応しました。メモリへのダウンロードが目的なのでタイプ3については空読みするようにしています。

★2019/08/12 追記
 CP/M-86のASM86独自のレコードタイプ(81H~88H)に下記のソースも含めて対応しました。

 HexLoader自体はアセンブリ言語で書き、nasmを使ってアセンブルしています。
 アセンブルは下のようなバッチファイルで行い、アセンブルで生成されたたbinファイルを自作のbin2state(バイナリからpicleのステートメントへ変換するツール)で変換し、picleのソースに埋め込んでいます。

nasm -l %1.lst -o %1.bin %1.asm
bin2state <%1.bin >%1.txt


 ソースは以下のとおりです。

HexLoaderのアセンブリソース
1 ;***************************** 2 ; Pic24V20 HexLoader 3 ; Ver0.02 supports ASM86 HexFile 4 ; Ver0.03 make compact a little 5 ; 2020/10/26 by skyriver 6 ;***************************** 7 8 9 CPU 8086 10 11 %define JMPS JMP SHORT 12 13 SEC_SZ EQU 512 ; sector size 14 WRK_START EQU 01e0H ; work start adr 15 16 FC_EXIT EQU 0 ; EXIT CP/M 17 FC_CONST EQU 1 ; CONST 18 FC_CONIN EQU 2 ; CONIN 19 FC_CONOUT EQU 3 ; CONOUT 20 FC_READ EQU 4 ; READ SD Card 21 FC_WRITE EQU 5 ; WRITE SD Card 22 FC_PUNCH EQU 6 ; PUNCH 23 FC_READER EQU 7 ; READER 24 25 SdBuf EQU WRK_START 26 PicWrk EQU SdBuf + SEC_SZ 27 28 STRUC tPic ; Pic I/F work area 29 00000000 .FuncNo RESB 1 ; function No 30 00000001 .RetVal RESB 1 ; return value 31 00000002 .CoData RESB 1 ; conout data 32 00000003 .SelDk RESB 1 ; selected disk 33 00000004 .Track RESB 2 ; track No 34 00000006 .DmaAdr RESB 2 ; DMA adr 35 00000008 .Sector RESB 1 ; sector No. 36 ENDSTRUC 37 38 ; *** memory assign *** 39 40 ; ffc00 ffc0:0000 code area 41 ; 42 ; ffde0 ffc0:01e0 SD buf 512byte 43 ; fffe0 ffc0:03e0 work 16byte 44 ; ffff0 ffff:0000 reset jmp 45 46 47 ; SEGMENT CODE ABSOLUTE=0xffc0 48 SEGMENT CODE 49 50 ORG 0 51 52 00000000 8CC8 START: MOV AX,CS 53 00000002 8ED8 MOV DS,AX 54 00000004 8ED0 MOV SS,AX 55 00000006 BCE001 MOV SP,WRK_START 56 00000009 31C0 XOR AX,AX 57 0000000B 8EC0 MOV ES,AX 58 59 0000000D BA0080 MOV DX,8000H 60 61 00000010 BB[2100] MOV BX,MESG 62 00000013 E83D00 CALL PUTS 63 00000016 E86D00 CALL LOAD 64 00000019 E82700 CALL CONIN ; read CR 65 0000001C E83000 CALL EXIT 66 0000001F EBFE JMPS $ 67 68 69 00000021 4865784C6F61646572- MESG: DB 'HexLoader Start',13,10,0 70 0000002A 2053746172740D0A00 71 00000033 20657272210D0A00 ERRMSG: DB ' err!',13,10,0 72 73 ; go pic nterface 74 ; AL <- Function No 75 ; AL -> return value 76 0000003B A2E003 PICSRV: MOV [PicWrk + tPic.FuncNo],AL 77 0000003E EE OUT DX,AL 78 0000003F A0E103 MOV AL,[PicWrk + tPic.RetVal] 79 00000042 C3 RET 80 81 82 ; get console status 83 ; AL -> 0FFH:data exist, 00H:no data 84 ;CONST: MOV AL,FC_CONST 85 ; JMPS PICSRV 86 87 ; input from console 88 ; AL -> data 89 90 00000043 B002 CONIN: MOV AL,FC_CONIN 91 00000045 EBF4 JMPS PICSRV 92 93 94 ; output to console 95 ; CL <- data 96 97 00000047 B003 CONOUT: MOV AL,FC_CONOUT 98 00000049 880EE203 MOV BYTE [PicWrk + tPic.CoData],CL 99 0000004D EBEC JMPS PICSRV 100 101 102 ; return to PIC world 103 104 0000004F B000 EXIT: MOV AL,FC_EXIT 105 00000051 EBE8 JMPS PICSRV 106 107 108 ; put string 109 ; BX <- string adr 110 111 00000053 8A0F PUTS: MOV CL,[BX] 112 00000055 43 INC BX 113 00000056 08C9 OR CL,CL 114 00000058 7405 JZ PUTSE 115 0000005A E8EAFF CALL CONOUT 116 0000005D EBF4 JMPS PUTS 117 0000005F C3 PUTSE: RET 118 119 120 ; read hex nible 121 ; AL -> data 122 00000060 E8E0FF RDNBL: CALL CONIN 123 00000063 2C30 SUB AL,'0' 124 00000065 3C0A CMP AL,10 125 00000067 7202 JC RDNBLE 126 00000069 04F9 ADD AL,10 + '0' - 'A' 127 0000006B C3 RDNBLE: RET 128 129 130 ; read byte data 131 ; AL -> byte data 132 133 0000006C E8F1FF RDBYTE: CALL RDNBL 134 0000006F D0E0 SHL AL,1 135 00000071 D0E0 SHL AL,1 136 00000073 D0E0 SHL AL,1 137 00000075 D0E0 SHL AL,1 138 00000077 88C7 MOV BH,AL 139 00000079 E8E4FF CALL RDNBL 140 0000007C 08F8 OR AL,BH 141 0000007E C3 RET 142 143 144 ; read hex word 145 ; AX -> data 146 0000007F E8EAFF RDWORD: CALL RDBYTE 147 00000082 88C4 MOV AH,AL 148 00000084 EBE6 JMPS RDBYTE 149 150 151 ; load hex file 152 153 00000086 E8BAFF LOAD: CALL CONIN 154 00000089 3C3A CMP AL,':' 155 0000008B 75F9 JNZ LOAD 156 157 0000008D E8DCFF CALL RDBYTE ; get byte count 158 00000090 88C3 MOV BL,AL 159 00000092 E8EAFF CALL RDWORD ; get address 160 00000095 89C7 MOV DI,AX 161 00000097 E8D2FF CALL RDBYTE ; get record type 162 163 0000009A 88C4 MOV AH,AL 164 0000009C 88C1 MOV CL,AL 165 0000009E 2480 AND AL,080H 166 000000A0 B0E0 MOV AL,080H + 'a' - 1 167 000000A2 7502 JNZ LOAD03 168 169 000000A4 B030 LOAD02: MOV AL,'0' 170 000000A6 00C1 LOAD03: ADD CL,AL 171 000000A8 E89CFF CALL CONOUT 172 000000AB 88E0 MOV AL,AH 173 174 000000AD 3C02 CMP AL,02H ; segment data 175 000000AF 7507 JNZ NXCK1 176 177 000000B1 E8CBFF TYP02: CALL RDWORD ; ** segment 178 000000B4 8EC0 MOV ES,AX 179 000000B6 EBCE JMPS LOAD 180 181 000000B8 3C85 NXCK1: CMP AL,085H 182 000000BA 73F5 JNC TYP02 183 184 000000BC 08C0 OR AL,AL ; data record 185 000000BE 750D JNZ NXCK2 186 187 000000C0 88D9 TYP00: MOV CL,BL 188 000000C2 E8A7FF TYP00A: CALL RDBYTE ; ** DATA 189 000000C5 268805 MOV [ES:DI],AL 190 000000C8 47 INC DI 191 000000C9 E2F7 LOOP TYP00A 192 000000CB EBB9 JMPS LOAD 193 194 000000CD 3C81 NXCK2: CMP AL,081H 195 000000CF 73EF JNC TYP00 196 197 000000D1 3C01 CMP AL,01H ; end of data 198 000000D3 7504 JNZ NXCK3 199 200 000000D5 E894FF CALL RDBYTE ; ** EOD 201 000000D8 C3 RET 202 203 000000D9 3C03 NXCK3: CMP AL,03H ; start address 204 000000DB 74A9 JZ LOAD ; not implement 205 206 000000DD BB[3300] MOV BX,ERRMSG 207 000000E0 E870FF CALL PUTS 208 000000E3 C3 RET
★2020/10/26 最新版に変更

 テスト用のヘキサファイルは手で作るよりは一般的なツールで作った方がいいのでLASMを使いました。LASMはソースが100行以下であれば無料で使えます。

テスト用データ作成のためのLASM用ソース
;++++++++++++++++++++++++++++++++ ; Test data for HexLoader ; for lasm assembler ; ; asm & link command ; lasm32 testdata.asm ; lil32 -hex -sdseg=0030 testdata.obj ; ; 2019/08/10 by skyriver ;++++++++++++++++++++++++++++++++ dseg segment byte data: db '0123456789ABCDEF' dseg ends end


 上のソース内にアセンブルとリンクの方法をコメントで書いていますが、dsegの値を0030Hにしてリンクして生成されたヘキサファイルの内容はこんな感じです。

:020000020030CC
:10000000303132333435363738394142434445464E
:00000001FF


 下記がHexLoaderのpicleのリスト表示後、実行し、上のヘキサファイルをTeraTermにコピペした際のログです。
 スタートメッセージを表示後、「201」と表示されていますが、これはV20側の処理で受信したヘキサファイルのレコードタイプを出力しているものです(81H~88Hは'a'~'h'で表示)。

HexLoader実行時のログサンプル
:l 1:# Pic24V20 HexLoader v0.03 2020/09/02 2:# by skyriver 3: 4:use LibCpm; 5:use LibSpi; 6: 7:var ProgWrk,_WrkVal,_PicDma,WrkTrk; 8: 9: 10:proc m( data ) { 11: MemWr( data ); 12:} 13: 14: 15:proc PicSrv() { 16: var i,fno,rval; 17: 18: while (1) { 19: while (LATC[-1]&$40) {} # wait ready off 20: CMCON[0] = CMCON[0]&$feff; # CMP1 off 21: PmpOn(); 22: PmpSetAdr(ProgWrk); 23: fno = MemRd(); # dummy 24: for (i=0;i<3;i=i+1) { 25: _WrkVal[i] = MemRd(); 26: } 27: fno = _WrkVal[0]; # function No 28: 29: if (fno=1) { # CONST 30: if (InpChk_()) { 31: rval = $ff; 32: } else { 33: rval = 0; 34: } 35: } 36: else if (fno=2) { # CONIN 37: rval = InpChar_(); 38: } 39: else if (fno=3) { # CONOUT 40: PrnChar_( _WrkVal[2] ); 41: } 42: else if (fno=0) { 43: break; 44: } else { 45: PrnStr_("\nFunc err"); 46: } 47: PmpSetAdr(ProgWrk+1); 48: MemWr(rval); 49: 50: PmpOff(); 51: BusRelease(); 52: CMCON[0] = CMCON[0]|$0100; # CMP1 on 53: } 54:} 55: 56: 57:proc main() { 58: var adr; 59: init(); 60: initPmp(); 61:# initSpi(); 62:# initSd(); 63: 64: ProgWrk = $ffe0; # work addr(fffe0) 65: _PicDma = $fde0; 66: _WrkVal = Alloc( 5 ); 67: WrkTrk = Alloc( 2 ); 68: 69: LATA[0]=LATA[0]|1; # on reset:a0 70: BusReq(); 71: LATA[0]=LATA[0]&$fffe; # off reset:a0 72: 73: PmpOn(); 74: 75: PmpSetAdr($07f0); 76: m($ea);m($00);m($00);m($c0);m($ff); 77: 78: adr = $400; # adr:ffc00 79: PmpSetAdr(adr); 80: 81: m($8c);m($c8);m($8e);m($d8);m($8e);m($d0);m($bc);m($e0); 82: m($01);m($31);m($c0);m($8e);m($c0);m($ba);m($00);m($80); 83: m($bb);m($21);m($00);m($e8);m($3d);m($00);m($e8);m($6d); 84: m($00);m($e8);m($27);m($00);m($e8);m($30);m($00);m($eb); 85: m($fe);m($48);m($65);m($78);m($4c);m($6f);m($61);m($64); 86: m($65);m($72);m($20);m($53);m($74);m($61);m($72);m($74); 87: m($0d);m($0a);m($00);m($20);m($65);m($72);m($72);m($21); 88: m($0d);m($0a);m($00);m($a2);m($e0);m($03);m($ee);m($a0); 89: m($e1);m($03);m($c3);m($b0);m($02);m($eb);m($f4);m($b0); 90: m($03);m($88);m($0e);m($e2);m($03);m($eb);m($ec);m($b0); 91: m($00);m($eb);m($e8);m($8a);m($0f);m($43);m($08);m($c9); 92: m($74);m($05);m($e8);m($ea);m($ff);m($eb);m($f4);m($c3); 93: m($e8);m($e0);m($ff);m($2c);m($30);m($3c);m($0a);m($72); 94: m($02);m($04);m($f9);m($c3);m($e8);m($f1);m($ff);m($d0); 95: m($e0);m($d0);m($e0);m($d0);m($e0);m($d0);m($e0);m($88); 96: m($c7);m($e8);m($e4);m($ff);m($08);m($f8);m($c3);m($e8); 97: m($ea);m($ff);m($88);m($c4);m($eb);m($e6);m($b5);m($00); 98: m($e8);m($b8);m($ff);m($3c);m($3a);m($75);m($f9);m($e8); 99: m($da);m($ff);m($88);m($c3);m($e8);m($e8);m($ff);m($89); 100: m($c7);m($e8);m($d0);m($ff);m($88);m($c4);m($88);m($c1); 101: m($24);m($80);m($b0);m($e0);m($75);m($02);m($b0);m($30); 102: m($00);m($c1);m($e8);m($9a);m($ff);m($88);m($e0);m($3c); 103: m($02);m($75);m($07);m($e8);m($c9);m($ff);m($8e);m($c0); 104: m($eb);m($ce);m($3c);m($85);m($73);m($f5);m($08);m($c0); 105: m($75);m($0d);m($88);m($d9);m($e8);m($a5);m($ff);m($26); 106: m($88);m($05);m($47);m($e2);m($f7);m($eb);m($b9);m($3c); 107: m($81);m($73);m($ef);m($3c);m($01);m($75);m($04);m($e8); 108: m($92);m($ff);m($c3);m($3c);m($03);m($74);m($a9);m($bb); 109: m($33);m($00);m($e8);m($6e);m($ff);m($c3); 110: 111: PmpOff(); 112: 113: LATA[0]=LATA[0]|1; # on reset:a0 114: BusRelease(); 115: Timer_ = 1; 116: while ( Timer_ ); 117: LATA[0]=LATA[0]&$fffe; # off reset:a0 118: 119: while ((LATC[-1]&$40)=0); # wait ready on 120: 121: PicSrv(); 122: 123: BusReq(); 124:} :run HexLoader start 201 :
★2020/09/02 最新版に変更

 ヘキサファイルをダウンロード後のメモリ内容を確認した結果を以下に貼っておきます。
 0x0300からのデータがヘキサファイル内容のように「0123・・・DEF」になっていることから正常にダウンロードできたものと判断できます。

ヘキサファイルロード結果の確認
:l 1:# Pic24V20 dump 2:# by skyriver 3: 4:use LibCpm; 5:use LibSpi; 6: 7: 8:proc main() { 9: var adr; 10: init(); 11: initPmp(); 12:# initSpi(); 13:# initSd(); 14: 15: LATA[0]=LATA[0]|1; # on reset:a0 16: BusReq(); 17: LATA[0]=LATA[0]&$fffe; # off reset:a0 18: 19: PmpOn(); 20: dump($300); 21:} :run 0300 : 30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 0310 : 0E 8D DC 81 31 D7 85 3B DD 97 58 AD 02 F5 12 6E 0320 : 59 D3 97 8C 40 B4 20 B9 B1 FD A9 5C 00 59 40 66 0330 : A7 AD 93 DD A1 D7 46 FF 19 E8 23 F9 11 5D 04 FF 0340 : B8 8D 89 29 40 7F 00 6F 6C FC 08 7E C5 7A 11 F5 0350 : D4 97 06 F8 89 AF 2A C4 60 E5 B1 FB 00 75 08 76 0360 : 59 8F A8 1C 02 8B 02 3B 24 FA 60 AB 10 39 20 E6 0370 : 51 9C 06 F7 9B 2E 0A FB 69 DE A1 57 10 6E 02 EE :


★2019/08/12 追記
 CP/M-86のasm86が出力するhexファイルの中にタイプが81H等のインテルヘキサファイルフォーマットに反するレコードがありました。
 調べてみたところ、CP/M-86システムガイドの中にasm86だけが使う拡張タイプについて書いてありましたので貼っておきます。

asm86での拡張ヘキサファイルフォーマット



[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(1) 
共通テーマ:趣味・カルチャー