今回は、CP/Mのシステムをブートするためのbコマンドを実装したいと思います。
bコマンドについては今後SDCARDに実装するCP/Mシステムができた時点でコマンドを実行することができます。Bコマンドはそれまでちょっとだけおあずけです。
bコマンドを実装していきます。
bコマンドを実行するか確認してから、cmd17とcmd24、cmd18,cmd12のコマンドエリアをram領域にコピーし、SDCARDを初期化します。
bコマンドでは、SDCRADからブロックを読み込むために、cmd18を使用しました。cmd18はマルチブロック読み出しコマンドで、連続したブロックを効率よく読み込むことができます。
今後実装するCP/MシステムのSDカードでの配置は、最初のトラック0x00の第0セクタから0x0b分までをCCP+BDOSに、0x0bから0x04文をbiosに割り当てます。
パラメータを指定した後、spi_read_goでsdcardから読み込みします。
システムトラックだけは、1ブロック512byteで読み込みします
(CP/Mファイルシステムは、BIOS上でのプログラムを簡略化するために1セクタ128byteになっています。)
読み込みが終了したら、0x0000-0x7fffのrom領域をramに切り替えるために、切り替えプログラム(boot_move_prog:)を0x8000にコピーして、制御を0x8000に移し、ROMからRAMに切り替え(CBAR=0x00)のち、メモリ及びI/Oのwaitを0x00(waitなし)に設定してからBIOSの先頭にジャンプして、CP/Mに制御を移します。
cpm_boot:
ld hl,boot_yes_msg
call msgout
call getchar
cp "y"
ret nz
call cr
call cmd17_24_copy ;command rom >> ram area copy
call spi_card_init ;sdcard initialize
ld hl,0x0000 ;CP/M system block 0x0000 start
ld (rw_block_no),hl
ld hl,0x000b ;ccp+bdos >0x0b (512byte * 0x000b)
ld (rw_block),hl
ld hl,0xdc00 ;62K cp/m ccp top addr >> 0xdc00
ld (rw_addr),hl
call spi_read_go
cp 0x01
ret z
ld hl,0x000b ;CP/M bios block 0x000b start
ld (rw_block_no),hl
ld hl,0x0004 ;bios >0x04 (512byte * 4 bios area)
ld (rw_block),hl
ld hl,0xf200 ;62K cp/m bios top addr >> 0xf200
ld (rw_addr),hl
call spi_read_go
cp 0x01
ret z
ld hl,cpm_boot_msg
call msgout
ld hl,boot_move_prog ;64K swiching ram progrum copy at temp_addr
ld de,temp_addr ;transfer boot_move_prog ~ boot_move_end >>temp_addr(0x8000)
ld bc,boot_move_end
ldir
ld hl,temp_addr
jp (hl) ;temprary address jump(0x8000)
;
boot_move_prog: ;transfer address (temp_addr:0x8000)
xor a ;ram 0x0000 to 0x7fff setting
out0 (CBAR),a
nop
nop
in0 a,(DCNTL)
res 7,a ;MWI1=0
res 6,a ;MWI0=0 Memory wait state =0
res 5,a ;IWI1=0
res 4,a ;IWI0=0 I/O wait state =0
out0 (DCNTL),a
nop
nop
jp 0xf200 ;62K CP/M bios top address
boot_move_end:
今回のモニタソースとHEXファイルは次のとおりです。
次回は、SDCARDのファイルシステムの作成を行っていきたいと思います。
; HD64180 monitor ver0.72(SPI+boot) by Pinecone 2020/12/15
;
; HD64180 cpu
; rom 0000h -- 7fffh
; ram 8000h -- ffffh(MMU)
; clock 8MHz
; HD64180 serial communication (ch0)
; extemal Clock 307.2KHz(4.9152MHz TC74HC4040 1/16 Frequency division)
; Band Rate:19200 8bits 1Stopbits none Parity (81N)
; assembler
; program start 0000H
; main 0100H
;
; assemblers ASxxxx and ASlink V5.10
; file name HD64180_moni072_spi_boot.asm
; $ asz80 -l -s -o HD64180_moni072_spi_boot.asm
; $ aslink -i HD64180_moni072_spi_boot
; $ rom-writer TL866-2 plus HD64180_moni072_spi_boot.ihx
;
.hd64
;;8255 Parallel port
PPIA .equ 0x80 ;PPI-A PORT DATA REG
PPIB .equ 0x81 ;PPI-B PORT DATA REG
PPIC .equ 0x82 ;PPI-C PORT DATA REG
PPICNT .equ 0x83 ;PPI CONTL REG
;OUTPUT-PORT PPIC D7-D5
S_DI .equ 7 ;0b10000000 D7
S_CS .equ 6 ;0b01000000 D6
S_CLK .equ 5 ;0b00100000 D5
;INPUT-PORT PPIC D0
DO .equ 0 ;0b00000001 D0
TDR0 .equ 0x06 ;ch0 serial
RDR0 .equ 0x08
STAT0 .equ 0x04
CNTLA0 .equ 0x00
CNTLB0 .equ 0x02
;TDR1 .equ 0x07 ;ch1 serial
;RDR1 .equ 0x09
;STAT1 .equ 0x04
;CNTLA1 .equ 0x01
;CNTLB1 .equ 0x03
CBR .equ 0x38 ;i/o setting reg
BBR .equ 0x39
CBAR .equ 0x3a
;CMR .equ 0x1e
;CCR .equ 0x1f
DCNTL .equ 0x32
ram .equ 0x20 ;ram address 0x20000
cbar_set .equ 0x88 ;moni move temprary CBAR setting address 0x8000
temp_addr .equ 0x8000 ;moni move temprary address
.area TEST(ABS)
.org 0x0000
jp ram_setting
.org 0x0080
ram_setting:
ld a,cbar_set ;z80 ram address 0x8000 to 0xffff set cbar_set:0x88
out0 (CBAR),a
ld a,ram ;mmu ram address 0x20000 set ram:0x20
out0 (BBR),a
out0 (CBR),a
jp start
.org 0x100
start: ;cold start
ld sp,0x0000 ;stack pointer set
call com_init ;serial channel initialize
call ppi_init ;Parallel port A initialize
call cr
ld hl,msg_op ;opening message display
call msgout
call cpu_msg1
call cpu_msg2
call moni_area
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 "t"
call z,trance ;moni 64Kmemory trance
cp "a"
call z,spi_card ;read/write spi sd-card
cp "b"
call z,cpm_boot ;cpm system boot
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
crret_t:
call cr
ret
trance:
call call_yes_msg
call getchar
cp "y"
jr nz,crret_t
call cr
ld a,cbar_set ;ram 0x8000 to 0xffff
out0 (CBAR),a
ld a,ram
out0 (BBR),a
out0 (CBR),a
;ram 0x8000 to 0xffff
ld hl,0x0000 ;moni copy at temp_addr
ld de,temp_addr
ld bc,prog_end
ldir
ld hl,move_prog+temp_addr
jp (hl) ;temprary address jump
;
move_prog:
xor a ;ram 0x0000 to 0x7fff setting
out0 (CBAR),a
ld hl,temp_addr ;moni moveing at ram 0x0000 to prog_end
ld de,0x0000
ld bc,prog_end
ldir
ld hl,go_moni
jp (hl) ;ram monitor jump
;
go_moni:
call cr
ld hl,ram_msg
call msgout
ld sp,0x0000 ;stack pointer set
in0 a,(DCNTL)
res 7,a ;MWI1=0
res 6,a ;MWI0=0 Memory wait state =0
res 5,a ;IWI1=0
res 4,a ;IWI0=0 I/O wait state =0
out0 (DCNTL),a
nop
nop
jp start
cpu_msg1:
ld hl,cpu_msg_bbr ;BBR reg disply
call msgout
in0 a,(BBR)
call hex_a_disp
ld hl,cpu_msg_cbr ;CBR reg disply
call msgout
in0 a,(CBR)
call hex_a_disp
ld hl,cpu_msg_cbar ;CBAR reg disply
call msgout
in0 a,(CBAR)
call hex_a_disp
call cr
ret
cpu_msg2:
; ld hl,cpu_msg_clock ;clock divide
; call msgout
; in0 a,(CCR)
; rlca
; jr c,clock1
; ld a,"2"
; jr cpum1
;clock1: ld a,"1"
;cpum1:
; call putchar
; ld hl,cpu_msg_speed ;*2 Clock Multiplier
; call msgout
; in0 a,(CMR)
; rlca
; jr c,speed1
; ld a,"1"
; jr cpum2
;speed1: ld a,"2"
;cpum2:
; call putchar
ld hl,cpu_msg_wait_m ;Memory Wait State
call msgout
in0 a,(DCNTL)
rlca
rlca
and 0x03
add a,0x30
call putchar
ld hl,cpu_msg_wait_io ;i/o Wait State
call msgout
in0 a,(DCNTL)
rlca
rlca
rlca
rlca
and 0x03
cp 0x00
jr nz,iowait1
add a,0x30
jr iowait0
iowait1:
add a,0x31
iowait0:
call putchar
call cr
ret
moni_area:
ld hl,moni_area_msg ;monitor area
call msgout
ld hl,start
ld a,h
call hex_a_disp
ld a,l
call hex_a_disp
ld a,"-"
call putchar
ld hl,prog_end
ld a,h
call hex_a_disp
ld a,l
call hex_a_disp
call cr
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
cpm_boot:
ld hl,boot_yes_msg
call msgout
call getchar
cp "y"
ret nz
call cr
call cmd17_24_copy ;command rom >> ram area copy
call spi_card_init ;sdcard initialize
ld hl,0x0000 ;CP/M system block 0x0000 start
ld (rw_block_no),hl
ld hl,0x000b ;ccp+bdos >0x0b (512byte * 0x000b)
ld (rw_block),hl
ld hl,0xdc00 ;62K cp/m ccp top addr >> 0xdc00
ld (rw_addr),hl
call spi_read_go
cp 0x01
ret z
ld hl,0x000b ;CP/M bios block 0x000b start
ld (rw_block_no),hl
ld hl,0x0004 ;bios >0x04 (512byte * 4 bios area)
ld (rw_block),hl
ld hl,0xf200 ;62K cp/m bios top addr >> 0xf200
ld (rw_addr),hl
call spi_read_go
cp 0x01
ret z
ld hl,cpm_boot_msg
call msgout
ld hl,boot_move_prog ;64K swiching ram progrum copy at temp_addr
ld de,temp_addr ;transfer boot_move_prog ~ boot_move_end >>temp_addr(0x8000)
ld bc,boot_move_end
ldir
ld hl,temp_addr
jp (hl) ;temprary address jump(0x8000)
;
boot_move_prog: ;transfer address (temp_addr:0x8000)
xor a ;ram 0x0000 to 0x7fff setting
out0 (CBAR),a
nop
nop
in0 a,(DCNTL)
res 7,a ;MWI1=0
res 6,a ;MWI0=0 Memory wait state =0
res 5,a ;IWI1=0
res 4,a ;IWI0=0 I/O wait state =0
out0 (DCNTL),a
nop
nop
jp 0xf200 ;62K CP/M bios top address
boot_move_end:
spi_read_go:
ld hl,(rw_block_no)
ld a,(r7)
bit 6,a
jp z,spi_read_SD_ver2
ld a,h ;SDHC
ld (cmd18+03),a
ld a,l
ld (cmd18+04),a
jr spi_read01
spi_read_SD_ver2: ;Ver2
ld a,h
ld (cmd18+02),a
ld a,l
ld (cmd18+03),a
spi_read01:
call dummy_data
ld hl,cmd18
call cmd_out
call r1_resp
cp 0x00
jp nz,cmd18_err
sector_read_loop:
cmd18_st:
call r1_resp ;read data start response?
cp 0xfe ;data start byte 0xfe?
jr nz, cmd18_st
ld hl,(rw_addr)
ld b,0x00
cmd18_r:
call resp ;read data
ld (hl),a
inc hl
djnz cmd18_r
; 2st dummy read
ld b,0x00
cmd18_r2st: ;2st 256byte write
call resp
ld (hl),a
inc hl
djnz cmd18_r2st
ld (rw_addr),hl
call resp ;crc Skipping read
call resp ;crc Skipping read
ld hl,(rw_block)
dec hl
ld (rw_block),hl
ld a,h ;HL = 0?
or l
jr nz,sector_read_loop
ld d,0xff ;dummy data 0xff(cs low)
call spi_8bit
ld hl,cmd12 ;stop cmd
call cmd_out ;cmd12 Issue
ld d,0xff
call spi_8bit
call r1_resp
cp 0x00 ;response is 0x00 read mode OK?
jr nz,cmd18_err
cmd18_wch:
call resp
cp 0x00
jr z,cmd18_wch
call set_cs
xor a
ret
;; 1 sector write
cmd18_err:
cmd18_err2:
ld hl,cmd25_err_msg
call msgout
call set_cs
ld a,0x01
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
call set_cs ;CS="H"
xor a
ret
cmd17_err:
pop hl
ld hl,cmd17_err_msg
call msgout
call set_cs ;CS="H"
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 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
call set_cs ;CS="H"
xor a
ret
cmd24_err:
pop hl
cmd24_err2:
ld hl,cmd24_err_msg
call msgout
call set_cs ;CS="H"
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
ld b,0x06
ld hl,m_cmd18
ld de,cmd18
cmd18_copy:
ld a,(HL)
ld (DE),a
inc hl
inc de
djnz cmd18_copy
ld b,0x06
ld hl,m_cmd12
ld de,cmd12
cmd12_copy:
ld a,(HL)
ld (DE),a
inc hl
inc de
djnz cmd12_copy
ret
spi_card_init:
xor a
set S_CS,a ;CS="H"
set S_DI,a ;DI="H"
out0 (PPIC),a
ld b,80 ;80 clok output
call loopspii
xor a
out0 (PPIC),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
call set_cs
ret
SD_ver2:
ld hl,sd_ver2_msg
call set_cs
jr init_msg
cmd0_out:
ld hl,cmd0
call cmd_out
call r1_resp
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
ld a,0x01
ret
cmd55_out:
call dummy_data
ld hl,cmd55
call cmd_out
call r1_resp
ret
acmd41_out:
call dummy_data
ld hl,acmd41 ;sd-card Initialize
call cmd_out
call r1_resp
cp 0x00
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
pop af
ret
dummy_data:
xor a
set S_CS,a ;CS="H"
set S_DI,a ;DI="H"
out0 (PPIC),a
ld b,8 ;1clok output
call loopspii
xor a
set S_CS,a ;CS="H"
set S_DI,a ;DI="H"
out0 (PPIC),a
ret
loopspii:
res S_CLK,a ;CLK L
out0 (PPIC),a
nop
nop
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out0 (PPIC),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
out0 (PPIC),a
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out0 (PPIC),a
in0 a,(PPIC)
rrca
rl e
djnz loopspi
xor a
set S_DI,a ;DI H
out0 (PPIC),a
pop bc
ret
set_cs:
xor a
set S_CS,a ;CS="H"
set S_DI,a ;DI="H"
out0 (PPIC),a
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:in0 a,(STAT0) ;ch0 serial input
rlca
jr nc,getchar
in0 a,(RDR0)
ret
putchar:push af ;ch0 seriai output
com_out:in0 a,(STAT0)
bit 1,a
jr z,com_out
pop af
out0 (TDR0),a
ret
com_init:
push af
ld a,0x64
out0 (CNTLA0),a
ld a,0x07
out0 (CNTLB0),a
; ld a,0x64
; out0 (CNTLA1),a
; ld a,0x07
; out0 (CNTLB1),a
pop af
ret
ppi_init:
ld a,0b10000001 ;PPIA mode0,output PPIB mode0,output
out (PPICNT),a ;PPIC C7-C4 output,C3-C0 input
ret
msg_op: .str "Monitor HD64180 CPU ver0.72(SPI+boot) by Pinecone 2020/12/15"
.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 "t ram area trance monitor jump"
.db 0x0d
.str "b CP/M system boot at SDCARD"
.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
yes_msg:
.str " Yes:"
.db 0x00
cpu_msg_cbr:
.str " CBR:"
.db 0x00
cpu_msg_bbr:
.str " BBR:"
.db 0x00
cpu_msg_cbar:
.str " CBAR:"
.db 0x00
cpu_msg_clock:
.str " clock:1/"
.db 0x00
cpu_msg_speed:
.str " speed:*"
.db 0x00
cpu_msg_wait_m:
.str " wait memory:"
.db 0x00
cpu_msg_wait_io:
.str " wait i/o:"
.db 0x00
moni_area_msg:
.str " monitor area:"
.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
cmd25_err_msg:
.str "cmd25 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
ram_msg:
.str "RAM area switching monitor"
.db 0x0d
.db 0x00
boot_yes_msg:
.db 0x0d
.str "CP/M boot ? yes:"
.db 0x00
cpm_boot_msg:
.str "CP/M boot ...."
.db 0x0d
.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_cmd18:
.db 0x52
.db 0x00
.db 0x00
.db 0x00
.db 0x00
.db 0xff
m_cmd12:
.db 0x4c
.db 0x00
.db 0x00
.db 0x00
.db 0x00
.db 0xff
m_cmd24:
.db 0x58
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
prog_end:
.org 0xff00
cmd17:
.db 0x51
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
cmd18:
.db 0x52
.db 0x00
.db 0x00
.db 0x00
.db 0x00
.db 0xff
cmd12:
.db 0x4c
.db 0x00
.db 0x00
.db 0x00
.db 0x00
.db 0xff
cmd24:
.db 0x58
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
r7:
.ds 4
rw_block_no:
.ds 2
rw_block:
.ds 2
rw_addr:
.ds 2
HEXファイル
:03000000C38000BA
:100080003E88ED393A3E20ED3939ED3938C300016B
:20010000310000CDCE08CDDB08CD6C0121E008CDAD08CDD101CDF901CD2B023E3ECDC10824
:20012000CDB708CDC108FE3FCC6501FE64CC3803FE6DCC4E03FE6CCCA502FE6ACC5002FEDC
:2001400069CC8203FE63CC7A02FE74CC7601FE61CCC104FE62CCC103FE0D28BFFE0028BBD4
:20016000CD6C0118B6211E09CDAD08C93E0DCDC108C9CD6C01C9CDB803CDB708FE7920F29A
:20018000CD6C013E88ED393A3E20ED3939ED393821000011008001140CEDB0219F81E9AF9B
:2001A000ED393A21008011000001140CEDB021B201E9CD6C01219A0BCDAD08310000ED38DA
:2001C00032CBBFCBB7CBAFCBA7ED39320000C3000121B40ACDAD08ED3839CD740821AE0AF8
:2001E000CDAD08ED3838CD740821BA0ACDAD08ED383ACD7408CD6C01C921D40ACDAD08ED57
:2002000038320707E603C630CDC10821E20ACDAD08ED383207070707E603FE002004C630EE
:200220001802C631CDC108CD6C01C921ED0ACDAD082100017CCD74087DCD74083E2DCDC1D4
:200240000821140C7CCD74087DCD7408CD6C01C93E20CDC108CD1D08FE00201A3E20CDC1BD
:20026000083E79CDC1083E3ACDC108CDB708FE792004CD6C01E9CD6C01C93E20CDC108CD0D
:200280001D08FE0020F03E20CDC1083E79CDC1083E3ACDC108CDB708FE7920DACD6C011194
:2002A000A402D5E9C9CDDF02FEFF2819FE0120F53E0DCDC1083E4FCDC1083E4BCDC1083EB0
:2002C0000DCDC108C93E0DCDC1083E45CDC1083E52CDC1083E52CDC1083E0DCDC108C93E84
:2002E0000DCDC1081600CDB708FE3A2048CD1808457A8057CD1D08E5DDE17A858457CD1842
:20030000087DFE002020CD1808DD7500DD237D825710F3CD18087A85FE002019CDB708FED5
:200320000A20123E00C9FE01200BCD18087DFEFF20033E01C93EFFC93E20CDC108CD1D08D2
:20034000FE002803FDE5E1CD4308E5FDE1C93E20CDC108CD1D08FE0028063E0DCDC108C951
:200360003E20CDC1087ECD74083E20CDC108E5CD1808FE002803E1AFC94DE1713E0DCDC102
:2003800008C93E20CDC108CD1808FE0028063E0DCDC108C93E20CDC10806004DED78CD74E8
:2003A000083E20CDC108CD1808FE002802AFC97DED793E0DCDC108C9E521A80ACDAD08E10C
:2003C000C921B60BCDAD08CDB708FE79C0CD6C01CD9F06CDD806210000221CFF210B00222A
:2003E0001EFF2100DC2220FFCD3404FE01C8210B00221CFF210400221EFF2100F22220FFB5
:20040000CD3404FE01C821C80BCDAD08211B04110080013404EDB0210080E9AFED393A005A
:2004200000ED3832CBBFCBB7CBAFCBA7ED39320000C300F22A1CFF3A18FFCB77CA49047CF5
:200440003209FF7D320AFF18087C3208FF7D3209FFCD99072106FFCDD807CDC907FE00C282
:20046000B504CDC907FEFE20F92A20FF0600CDD107772310F90600CDD107772310F92220EA
:20048000FFCDD107CDD1072A1EFF2B221EFF7CB520D016FFCDE607210CFFCDD80716FFCDB8
:2004A000E607CDC907FE00200CCDD107FE0028F9CD0F08AFC921630BCDAD08CD0F083E0134
:2004C000C9CDB708FE69CC7E06FE72CCD404FE77CCCA05C921050BCDAD08CD1D08FE002858
:2004E00005CD6C01AFC93A18FFCB77CAF8047C3203FF7D3204FF18087C3202FF7D3203FF0A
:2005000021260BCDAD08CD1D08FE002805CD6C01AFC9CDB803CDB708FE79C26E07E5CD992B
:20052000072100FFCDD807CDC907FE002040CDC907FEFE20F90600E1CDD107772310F90606
:2005400000CDD107772310F9CDD107CDD10716FFCDE607010002ED423E0DCDC108CD7905DC
:20056000CDC108CD7905CDC108CD0F08AFC9E1214D0BCDAD08CD0F08C9C50600E521710AD3
:20058000CDAD08E17CCD74087DCD74083E20CDC108CDC1087E23CD740878FE01282378E6D9
:2005A0000FFE0128073E20CDC10818153E0DCDC1087CCD74087DCD74083E20CDC108CDC1EF
:2005C0000810D13E0DCDC108C1C921150BCDAD08CD1D08FE002805CD6C01AFC93A18FFCB19
:2005E00077CAEE057C3215FF7D3216FF18087C3214FF7D3215FF21320BCDAD08CD1D08FECD
:20060000002805CD6C01AFC9CDB803CDB708FE79C26E07E5CD99072112FFCDD807CDC9076C
:20062000FE00C2730616FECDE607E106005623CDE60710F906005623CDE60710F916FFCD6C
:20064000E607CDE607CDC907E60FFE052026CDD107FE0028F9CD9907010002ED423E0DCD9D
:20066000C108CD7905CDC108CD7905CDC108CD0F08AFC9E121580BCDAD08CD0F08C9CD9F93
:2006800006217F0BCDAD08CDB803CDB708FE79C26E07CD6C01CDD80621FC0ACDAD08C90608
:2006A0000621FC0B1100FF7E12231310FA0606210E0C1112FF7E12231310FA060621020CB8
:2006C0001106FF7E12231310FA060621080C110CFF7E12231310FAC9AFCBF7CBFFED39825B
:2006E0000650CDAF07AFED3982CD2507FE01C27207CD2F07FE01C27207CD4D07FE01C27206
:2007000007CD5A07CD7E073A18FFCB7FCA7207CB77280A216E0BCDAD08CD0F08C921750B96
:20072000CD0F0818F121D80BCDD807CDC907C9CD990721DE0BCDD807CDC907FE01C006042D
:200740002118FFCDD107772310F93E01C9CD990721F00BCDD807CDC907C9CD990721E40BF9
:20076000CDD807CDC907FE00C8CD4D0718ECCD6C01C9213F0BCDAD08CD6C01C30001CD99F1
:200780000721EA0BCDD807CDC907F506042118FFCDD107772310F9F1C9AFCBF7CBFFED3959
:2007A000820608CDAF07AFCBF7CBFFED3982C9CBAFED39820000000000000000CBEFED3978
:2007C00082000000000010E7C9CDD107FEFF28F9C916FFCDE6077BC9E5C5060656CDE60772
:2007E0002310F9C1E1C9C50E000608AFCB021FCBAFED3982000000000000CBEFED3982ED75
:2008000038820FCB1310E4AFCBFFED3982C1C9AFCBF7CBFFED3982C9C506021803C506042F
:20082000210000180429292929CDB708CDC108CD8708FEFF2809E60FB56F10E9C1AFC93EA2
:20084000FFC1C93E0DCDC108E521710ACDAD08E17CCD74087DCD74083E20CDC108CDC10835
:2008600006107E23CD74083E20CDC10810F43E0DCDC108C9F50F0F0F0FCDA108CDC108F1A8
:20088000CDA108CDC108C9D6303813FE0A380ED611FE063806D620FE063003C60AC93EFFB8
:2008A000C9E60FFE0A3803C637C9C630C97EFE00C8CDC1082318F6ED38040730FAED380820
:2008C000C9F5ED3804CB4F28F9F1ED3906C9F53E64ED39003E07ED3902F1C93E81D383C94E
:2008E0004D6F6E69746F7220484436343138302043505520766572302E3732285350492BE6
:20090000626F6F74292062792050696E65636F6E6520323032302F31322F31350D000D3F4A
:20092000202048656C700D6420206D656D6F72792064756D700D6D20206D656D6F7279205B
:200940006368616E676520202061646472657373206F6C64206E65770D6C20206865782004
:2009600066696C65206C6F61640D6A20206A756D700D692020692F6F2072656769737465D4
:200980007220202020692F6F2D61646472657373206F6C64206E65770D63202063616C6C36
:2009A0000D74202072616D2061726561207472616E6365206D6F6E69746F72206A756D70DC
:2009C0000D62202043502F4D2073797374656D20626F6F74206174205344434152440D618C
:2009E00069207370692873642D636172642920496E697469616C697A6174696F6E0D61726B
:200A0000207370692873642D63617264292072656164202028353132627974652F626C6F9F
:200A2000636B2920203078303030302D307866666666207365740D617720737069287364EE
:200A40002D63617264292077726974652028353132627974652F626C6F636B29202030787C
:200A6000303030302D307866666666207365740D006164647220202B30202B31202B322081
:200A80002B33202B34202B35202B36202B37202B38202B39202B41202B42202B43202B44B9
:200AA000202B45202B460D00205965733A00204342523A00204242523A0020434241523AAA
:200AC0000020636C6F636B3A312F002073706565643A2A002077616974206D656D6F72792D
:200AE0003A00207761697420692F6F3A00206D6F6E69746F7220617265613A004F4B0D00C4
:200B00004552520D00207265616420626C6F636B204E6F3A0020777269746520626C6F63D6
:200B20006B204E6F3A00207361766520616464723A0020777269746520616464723A0053DC
:200B4000706920496E6974204572720D00636D643137204572720D00636D6432342045724F
:200B6000720D00636D643235204572720D003A534448430D003A534420566572320D00201F
:200B80007370692873642D636172642920496E697469616C697A65203A0052414D206172BB
:200BA000656120737769746368696E67206D6F6E69746F720D000D43502F4D20626F6F745A
:200BC000203F207965733A0043502F4D20626F6F74202E2E2E2E0D00400000000095480026
:200BE0000001AA876940FF8000FF7A00000000FF7700000000FF5000000200FF5100000209
:140C000000FF5200000000FF4C00000000FF5800000200FFEC
:18FF00005100000200FF5200000000FF4C00000000FF5800000200FFA2
:00000001FF