拡張したSRAM上で動作するモニタを自動的に転送するコマンドを追加しました。

コマンドは”t”です。
合わせて、オープニング時にBBR、CBR、CBARの内容を表示します。
また、Z8S180のクロックの分周比、倍率、メモリとI/Oのwait状況
モニタのメモリ配置エリアを表示するようにしました

実際に実行した様子は次のようになります。
上段がリセット直後のFRAM上のモニタのオープニングメッセージ
下段がtコマンドを実行したSRAM上のモニタのオープニングメッセージです
[asm] Monitor Z180 CPU ver0.72 by Pinecone 2017/3/20
BBR:00CBR:00 CBAR:F0
clock:1/2 speed:*1 wait memory:3 wait i/o:4
monitor area:0100-05D5
>t Yes:

Monitor Z180 CPU ver0.72 by Pinecone 2017/3/20
BBR:20CBR:20 CBAR:00
clock:1/1 speed:*2 wait memory:0 wait i/o:1
monitor area:0100-05D5
>

[/asm]

このバージョンのモニタのソースを展開しました。
前より長くなってます^^;
[asm] ; Z180 monitor ver0.72 by Pinecone 2017/3/20
;
; Z8S180 cpu
; 0000h -- 7fffh
; External clock 16MHz

; Z8S180 serial communication (Ch0)
; extemal Clock

; assembler
; program start 0000H
; main 0100H
;
; assemblers ASxxxx and ASlink V5.10
; file name moni72.asm
; $ asz80 -l -s -o moni72.asm
; $ aslink -i moni72
; $ sudo python hexwrite.py moni72.ihx
;

.z180

.area TEST(ABS)

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

.org 0x0000
jp start

.org 0x100

start: ;cold start
ld sp,0x8000 ;stack pointer set
call com_init ;serial channel 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 disply?
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 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

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:
ld sp,0x8000
in0 a,(CMR) ;XTAL*2
set 7,a
out0 (CMR),a
in0 a,(CCR) ;XTAL/1
set 7,a
out0 (CCR),a

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 =1
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
add a,0x31
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
call call_yes_msg
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
call call_yes_msg
call getchar
cp "y"
jr nz,crret
call cr
ld de,callret
push de
jp (HL)
callret:
ret

call_yes_msg:
push hl
ld hl,yes_msg
call msgout
pop hl
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
call cr
ld hl,ok_msg
call msgout
ret

loadhexerr:
call cr ;hex file read skipret
ld hl,err_msg
call msgout
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 memory display call putchar ld b,0x00 ld c,l in a,(c) call hex_a_disp ld a," " call putchar call input_l ;new memory conntents input cp 0x00 jr z,ioreg2 xor a ret ioreg2: ld a,l ;memory contents update out (c),a ld a,0x0d call putchar 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)
; call putchar1 ;ch0 serial monitor >> ch1 output
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

;getchar1:in0 a,(STAT1)
; rlca
; jr nc,getchar1
; in0 a,(RDR1)
; ret
;putchar1:push af
;com_out1:in0 a,(STAT1)
; bit 1,a
; jr z,com_out1
; pop af
; out0 (TDR1),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
;
msg_op: .str "Monitor Z180 CPU ver0.72 by Pinecone 2017/3/20"
.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
.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
prog_end:
.end

[/asm]
おすすめの記事