SSブログ
English Version

Z80GALの構想(その11)IPLの製作 [Z80]

 前回の「Z80GALの構想(その10)回路図とパターン設計」で書いたようにプリント基板のパターン設計ができたのでseeedさんへ発注しましたが、その後2ヶ所ミスを発見orz
 1つはシルクが2022年になっていました(未来から来た基板w)、あと1つはパターンをカットすれば対応できそうですがプリント基板が届いてから具体的な対処を検討します。

 今回は未作成だったIPLを作ったので書いてみます。IPLを先頭セクタに保存し、リセット時に先頭セクタをメモリに読込み、実行することでCP/Mが立ち上るようになります。
 IPLは1つのセクタ(128バイト)に入れるため、SDカードのブロック読込みはEEPROMからRAMへコピーされたコード内の処理を呼び出すようにしました。
 また、割込み処理の切替えは少し面倒なのでシリアル出力は割込みを使用せずソフトでタイミングを取った専用のものを使用するようにしました。

 短いので全ソースを貼っておきます。

Z80GAL IPL(Initial Program Loader)
;+++++++++++++++++++++++++++++++++++++ ; Z80GAL IPL(Initial Program Loader) ; Ver 0.02 2020/11/29 by skyriver ;+++++++++++++++++++++++++++++++++++++ 8000 IPLENT EQU 08000H ; IPL start address 0080 SECSIZE EQU 128 ; sector size 0200 SDBLKSZ EQU 512 ; SD card block size 0004 SECBLK EQU (SDBLKSZ / SECSIZE) ; sec par block 003E MSIZE EQU 62 ; CP/M memory size A800 BIAS EQU (MSIZE-20) * 1024 DC00 CCP EQU 3400H + BIAS ; CCP start address E406 BDOS EQU CCP + 806H ; BDOS start address F200 BIOS EQU CCP + 1600H ; BIOD start address F200 BOOT EQU BIOS FE00 BIOSEND EQU 0FE00H ; BIOS end addtress 0045 RDSEC EQU (BIOSEND - CCP) / SECSIZE + 1 ; add 1sec for IPL 0012 RDBLK EQU (RDSEC + SECBLK -1) / SECBLK 0380 BlkRd EQU 00380H ; SD card block read func HL<-read adrs 0384 SdBlkNo EQU 00384H ; SD block number(big endian) 0386 SdBlkL EQU 00386H ; SD block low number(big endian) 000D CR EQU 13 000A LF EQU 10 ;*** Z80GAL I/O address *** 0080 adBASE EQU 080H ; I/O base address 00E0 adRAM EQU (adBASE + 60H) ; select memory RD D0=1:RAM, 0:ROM 00C0 adSdCs EQU (adBASE + 40H) ; set SD's CS D0=1:active 00A0 AdSd EQU (adBASE + 20H) ; write D0:SDO D1:CLK, read D0:SDI D1:CS 0080 AdSeri EQU (adBASE + 00H) ; serial D0 write:Tx read:Rx 0001 SD_DAT EQU 1 0002 SD_CLK EQU 2 0001 SD_CS EQU 1 .Z80 0000' ASEG ORG IPLENT 8000 F3 IPL: DI 8001 21 8034 LD HL,MSGLD 8004 CD 8054 CALL Puts 8007 21 0000 LD HL,0 800A 22 0384 LD (SdBlkNo),HL 800D 22 0386 LD (SdBlkL),HL 8010 21 DB80 LD HL,CCP - SECSIZE 8013 01 1200 LD BC,RDBLK * 256 + 0 ; B:Blk counter, C:Blk No. 8016 79 IPL10: LD A,C 8017 32 0387 LD (SdBlkL + 1),A ; set Block No. 801A 0C INC C 801B CD 0380 CALL BlkRd 801E B7 OR A 801F 20 0B JR NZ,IPLERR 8021 10 F3 DJNZ IPL10 8023 21 8049 LD HL,MSGOK 8026 CD 8054 CALL Puts 8029 C3 F200 JP BOOT 802C 21 804C IPLERR: LD HL,MSGERR 802F CD 8054 CALL Puts 8032 18 FE JR $ 8034 0D 0A 20 43 MSGLD: DB CR,LF," CP/M loading ... ",0 8038 50 2F 4D 20 803C 6C 6F 61 64 8040 69 6E 67 20 8044 2E 2E 2E 20 8048 00 8049 6F 6B 00 MSGOK: DB "ok",0 804C 49 50 4C 20 MSGERR: DB "IPL err",0 8050 65 72 72 00 8054 7E Puts: LD A,(HL) 8055 23 INC HL 8056 B7 OR A 8057 C8 RET Z 8058 CD 805D CALL Putc 805B 18 F7 JR Puts ;*** softqare serial *** ; 9600bps 1bit length = 1000000/9600 = 104.17 us ; = (1000000/9600)/(1/20) = 2083.3 states(20MHz) 0823 STIMST EQU 2083 ; (10000/96*20) ; state par serial 1bit 009D STICNT EQU (STIMST-11-4-4-7-8+7-4-12)/13+1 ; serial out ; A <- data 805D B7 Putc: OR A ; 4 clear Cy(start bit) 805E 17 RLA ; 4 805F 0E 0A LD C,10 ; 7 set bit counter 8061 D3 80 Putc10: OUT (AdSeri),A ; 11 8063 1F RRA ; 4 8064 37 SCF ; 4 for stop bit 8065 06 9D LD B,STICNT ; 7 8067 10 FE DJNZ $ ; 13/8 8069 0D DEC C ; 4 806A 20 F5 JR NZ,Putc10 ; 12/7 806C C9 RET ; 10 END
★変更 2020/11/29 Putc処理のコードを短縮

 また、リセット後の立上り処理として、SDカードを挿している場合はCP/Mを起動し、SDカードが無い場合にはGAMEインタープリタを起動するようにしました。

 更にCP/M起動後にGAMEの世界に戻ったりGAMEからCP/Mを起動できるようにしてみました。下図がリセット後のCP/M起動から切替え操作例のキャプチャです。

CP/MとGAMEの切替え


 CP/Mが動作している状態でEEPROM内コードをRAMにコピー後に、0003Hから実行するとGAMEインタープリタが起動するようにしています。
 CP/MからGAMEへ移行するためには下記のリストのようにROM/RAM切替の影響を受けないメモリの後半(下記の場合は8000H)で動作するプログラムでEEPROMをアクティブにしてコードをRAMにコピー後、0003HへジャンプすることでGAMEインタープリタが立ち上がります。
 また、GAMEが動作している状態では、単に0000HへジャンプするだけでCP/Mが起動します。

CP/MからGAMEインタープリタ起動コマンドのソース
;+++++++++++++++++++++++++++++++++++++++ ; exit from CP/M-80 in Z80GAL ; Ver 0.01 2020/11/27 by skyriver ;+++++++++++++++++++++++++++++++++++++++ ;*** Z80GAL I/O address *** 0080 adBASE EQU 080H ; I/O base address 00E0 adRAM EQU (adBASE + 60H) ; select memory RD D0=1:RAM, 0:ROM 00C0 adSdCs EQU (adBASE + 40H) ; set SD's CS D0=1:active 00A0 AdSd EQU (adBASE + 20H) ; write D0:SDO D1:CLK, read D0:SDI D1:CS 0080 AdSeri EQU (adBASE + 00H) ; serial D0 write:Tx read:Rx 0001 SD_DAT EQU 1 0002 SD_CLK EQU 2 0001 SD_CS EQU 1 4000 CPYSIZE EQU 4000H ; ROM -> RAM copy size 8000 PROGADR EQU 8000H ; program execute address 0003 GOGAME EQU 0003H ; GAME exute entry .Z80 0000' ASEG ORG 0100H 0100 21 010E LD HL,RELPRG 0103 11 8000 LD DE,PROGADR 0106 01 0011 LD BC,ENDAD - EXTCPM 0109 ED B0 LDIR 010B C3 8000 JP PROGADR 010E RELPRG EQU $ .PHASE PROGADR 8000 F3 EXTCPM: DI 8001 AF XOR A 8002 D3 E0 OUT (adRAM),A ; select ROM 8004 21 0000 LD HL,0 8007 54 LD D,H 8008 5D LD E,L 8009 01 4000 LD BC,CPYSIZE 800C ED B0 LDIR 800E C3 0003 JP GOGAME 8011 ENDAD EQU $ END


★追記 2021/01/22
 CP/MからGAMEインタープリタの世界に移行するためには、ROMがアクティブな状態で0003Hから実行すればいいので、上記のGAMEインタープリタ起動コマンドをスリム化しました。

CP/MからGAMEインタープリタ起動コマンド改善版のソース
;+++++++++++++++++++++++++++++++++++++++ ; exit from CP/M-80 in Z80GAL ; Ver 0.02 2021/01/22 by skyriver ;+++++++++++++++++++++++++++++++++++++++ ;*** Z80GAL I/O address *** 0080 adBASE EQU 080H ; I/O base address 00E0 adRAM EQU (adBASE + 60H) ; select memory RD D0=1:RAM, 0:ROM 00C0 adSdCs EQU (adBASE + 40H) ; set SD's CS D0=1:active 00A0 AdSd EQU (adBASE + 20H) ; write D0:SDO D1:CLK, read D0:SDI D1:CS 0080 AdSeri EQU (adBASE + 00H) ; serial D0 write:Tx read:Rx 0001 SD_DAT EQU 1 0002 SD_CLK EQU 2 0001 SD_CS EQU 1 .Z80 0000' ASEG ORG 0100H 0100 21 DB 021H ; ld hl 0101 D3 E0 OUT (adRAM),A 0103 22 0001 LD (0001H),HL 0106 AF XOR A 0107 C3 0001 JP 1 END



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

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

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。