前回のZ80+8251+8255に引き続き、Z80+SIO+PIOについても、モニタを移植したいと思います。

まずは、SIOとPIOのポートの定義を変更します。

;; Z80 PIO 
PIOAD 	.equ 	0x88		;PIO-A PORT DATA REG
PIOAC	.equ	0x89		;PIO-A PORT CONTL REG
PIOBD	.equ	0x8a		;PIO-B PORT DATA REG
PIOBC	.equ	0x8b		;PIO-B PORT CONTL REG

;; Z80 SIO
SIOAD	.equ	0x84		;SIO A-CH DATA REG
SIOAC	.equ	0x85		;SIO A-CH CONTL REG
SIOBD	.equ	0x86		;SIO B-CH DATA REG
SIOBC	.equ	0x87		;SIO B-CH CONTL REG

同様にSIOとPIOの初期化ルーチンを変更します。

        call    sio_init        ;serial channel initialize
	call	pio_init	;Parallel port initialize
・
中略
・
sio_init:
	ld	b,0x0b
	ld	c,SIOBC
	ld	hl,SIO_INIT_TB_B
	otir
	ld	b,0x09
	ld	c,SIOAC
	ld	hl,SIO_INIT_TB_A
	otir	
	ret

pio_init:
	;; PIO-A PORT INIT
	ld	a,0x00		;int bector set
	out	(PIOAC),a
	ld	a,0b11001111	;mode 3 set(bit control)
	out	(PIOAC),a
	ld	a,0b00001111	;portA 7-4 output 3-0 input
	out	(PIOAC),a
	ld	a,0b00000111	;int disple
	out	(PIOAC),a
	ld	a,0b11111111	;mask bit
	out	(PIOAC),a

	;; PIO-B PORT INIT
	ld	a,0x00		;int bector set
	out	(PIOBC),a
	ld	a,0b11001111	;mode 3 set(bit control)
	out	(PIOBC),a
	ld	a,0b11111111	;portB 7-0 input
	out	(PIOBC),a
	ld	a,0b00000111	;int disple
	out	(PIOBC),a
	ld	a,0b11111111	;mask bit
	out	(PIOBC),a
	ret	
;

SIO_INIT_TB_A:
	.db	0x18		;ch RESET
	.db	0x14		;WR4 set ,int reset
	.db	0b01000100	;x16 8bitchar 1stopbit nonparity
	.db	0x03		;WR3 set
	.db	0b11000001	;rx 8bit char ,RxEnable
	.db	0x05		;WR5 set
	.db	0b01101000	;tx 8bit char ,TxEnable ,DTR=0 ,RTS=0
	.db	0x11		;WR1 set ,int reset
	.db	0b00000000	;non int
SIO_INIT_TB_B:
	.db	0x18		;ch RESET
	.db	0x02		;WR2 set
	.db	0x00		;int tabel 0x00
	.db	0x14		;WR4 set ,int reset
	.db	0b01000100	;x16 8bitchar 1stopbit nonparity
	.db	0x03		;WR3 set
	.db	0b11000001	;rx 8bit char ,RxEnable
	.db	0x05		;WR5 set
	.db	0b01101000	;tx 8bit char ,TxEnable ,DTR=0 ,RTS=0
	.db	0x11		;WR1 set ,int reset
	.db	0b00000000	;non int

SIOの1byte入出力ルーチンを変更します。

getchar:
	in     	a,(SIOAC)
	bit	0,a
        jr      z,getchar
	in      a,(SIOAD)
	ret

putchar:push	af
putchar01:
	in      a,(SIOAC)
        bit     2,a
        jr      z,putchar01
	pop	af
        out     (SIOAD),a
	ret

これで変更が行えたので、romに焼いて起動してみました。

Monitor Z80+SIO+PIO ver0.71  by Pinecone 2020/09/02                             
>?                                                                              
? Help                                                                          
d MemoryDump                                                                    
m MemoryChange                                                                  
l HexFileLoad                                                                   
j jump                                                                          
i I/oRegister                                                                   
c Call                                                                         
>m 8000 40 ff                                                                  
>m 8000 FF                                                                      
>

以下ソースファイルを展開しました。

; Z80+SIO+PIO monitor  ver0.71 by Pinecone 2020/09/02
;
; Z80 cpu
; rom 0000h -- 7fffh
; ram 8000h -- ffffh
; External clock 4.9142MHz

; SIO serial communication A-CH
; extemal Clock 0.6144MHz (4.9152MHz TC74HC4040 1/8 Frequency division)
; Band Rate:38400  8bits 1Stopbits none Parity (81N)

; assembler
;  program start 0000H
;  main          0100H
;
; assemblers  ASxxxx and ASlink V5.10
; file name Z80_SIO_PIO_moni.asm
; $ asz80 -l -s -o Z80_SIO_PIO_moni.asm
; $ aslink -i Z80_SIO_PIO_moni
; windows10 rom-writer TL866-2 plus z80_SIO_PIO_moni.ihx
;

        .z80
 
        .area TEST(ABS)
 
;; Z80 PIO 
PIOAD 	.equ 	0x88		;PIO-A PORT DATA REG
PIOAC	.equ	0x89		;PIO-A PORT CONTL REG
PIOBD	.equ	0x8a		;PIO-B PORT DATA REG
PIOBC	.equ	0x8b		;PIO-B PORT CONTL REG

;; Z80 SIO
SIOAD	.equ	0x84		;SIO A-CH DATA REG
SIOAC	.equ	0x85		;SIO A-CH CONTL REG
SIOBD	.equ	0x86		;SIO B-CH DATA REG
SIOBC	.equ	0x87		;SIO B-CH CONTL REG

        .org    0x0000
        jp      start
 
        .org    0x0100

start:                          ;cold start

        ld      sp,0x0000       ;stack pointer set
        call    sio_init        ;serial channel initialize
	call	pio_init	;Parallel port initialize
        ld      hl,msg_op       ;opening message display
        call    msgout
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      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

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


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:
	in     	a,(SIOAC)
	bit	0,a
        jr      z,getchar
	in      a,(SIOAD)
	ret

putchar:push	af
putchar01:
	in      a,(SIOAC)
        bit     2,a
        jr      z,putchar01
	pop	af
        out     (SIOAD),a
	ret

;
sio_init:
	ld	b,0x0b
	ld	c,SIOBC
	ld	hl,SIO_INIT_TB_B
	otir
	ld	b,0x09
	ld	c,SIOAC
	ld	hl,SIO_INIT_TB_A
	otir	
	ret

pio_init:
	;; PIO-A PORT INIT
	ld	a,0x00		;int bector set
	out	(PIOAC),a
	ld	a,0b11001111	;mode 3 set(bit control)
	out	(PIOAC),a
	ld	a,0b00001111	;portA 7-4 output 3-0 input
	out	(PIOAC),a
	ld	a,0b00000111	;int disple
	out	(PIOAC),a
	ld	a,0b11111111	;mask bit
	out	(PIOAC),a

	;; PIO-B PORT INIT
	ld	a,0x00		;int bector set
	out	(PIOBC),a
	ld	a,0b11001111	;mode 3 set(bit control)
	out	(PIOBC),a
	ld	a,0b11111111	;portB 7-0 input
	out	(PIOBC),a
	ld	a,0b00000111	;int disple
	out	(PIOBC),a
	ld	a,0b11111111	;mask bit
	out	(PIOBC),a
	ret	
;

SIO_INIT_TB_A:
	.db	0x18		;ch RESET
	.db	0x14		;WR4 set ,int reset
	.db	0b01000100	;x16 8bitchar 1stopbit nonparity
	.db	0x03		;WR3 set
	.db	0b11000001	;rx 8bit char ,RxEnable
	.db	0x05		;WR5 set
	.db	0b01101000	;tx 8bit char ,TxEnable ,DTR=0 ,RTS=0
	.db	0x11		;WR1 set ,int reset
	.db	0b00000000	;non int
SIO_INIT_TB_B:
	.db	0x18		;ch RESET
	.db	0x02		;WR2 set
	.db	0x00		;int tabel 0x00
	.db	0x14		;WR4 set ,int reset
	.db	0b01000100	;x16 8bitchar 1stopbit nonparity
	.db	0x03		;WR3 set
	.db	0b11000001	;rx 8bit char ,RxEnable
	.db	0x05		;WR5 set
	.db	0b01101000	;tx 8bit char ,TxEnable ,DTR=0 ,RTS=0
	.db	0x11		;WR1 set ,int reset
	.db	0b00000000	;non int

;

msg_op: .str    "Monitor Z80+SIO+PIO ver0.71  by Pinecone 2020/09/02"
        .db     0x0d
        .db     0x00
help_msg:
        .db     0x0d    
        .str    "? Help"
        .db     0x0d
        .str    "d MemoryDump"
        .db     0x0d
        .str    "m MemoryChange"
        .db     0x0d
        .str    "l HexFileLoad"
        .db     0x0d
        .str    "j jump"
        .db     0x0d
        .str	"i I/oRegister"
        .db	0x0d
        .str	"c Call"
        .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

	.end

アセンブルしたHEXファイルは下記の通りです。

:03000000C3000139
:20010000310000CD7203CD850321C203CD54033E3ECD6703CD5E03CD6703FE3FCC4A01FEA3
:2001200064CC3F02FE6DCC5502FE6CCCAC01FE6ACC5701FE69CC8902FE63CC8101FE0D28B1
:20014000CEFE0028CACD510118C521F703CD5403C93E0DCD6703C93E20CD6703CDC402FE6C
:2001600000201A3E20CD67033E79CD67033E3ACD6703CD5E03FE792004CD5101E9CD510123
:20018000C93E20CD6703CDC402FE0020F03E20CD67033E79CD67033E3ACD6703CD5E03FE02
:2001A0007920DACD510111AB01D5E9C9CDE601FEFF2819FE0120F53E0DCD67033E4FCD6720
:2001C000033E4BCD67033E0DCD6703C93E0DCD67033E45CD67033E52CD67033E52CD670347
:2001E0003E0DCD6703C93E0DCD67031600CD5E03FE3A2048CDBF02457A8057CDC402E5DDD5
:20020000E17A858457CDBF027DFE002020CDBF02DD7500DD237D825710F3CDBF027A85FE16
:20022000002019CD5E03FE0A20123E00C9FE01200BCDBF027DFEFF20033E01C93EFFC93E75
:2002400020CD6703CDC402FE002803FDE5E1CDEA02E5FDE1C93E20CD6703CDC402FE002835
:20026000063E0DCD6703C93E20CD67037ECD1B033E20CD6703E5CDBF02FE002803E1AFC9A5
:200280004DE1713E0DCD6703C93E20CD6703CDBF02FE0028063E0DCD6703C93E20CD670345
:2002A00006004DED78CD1B033E20CD6703CDBF02FE002802AFC97DED793E0DCD6703C9C5E5
:2002C00006021803C50604210000180429292929CD5E03CD6703CD2E03FEFF2809E60FB510
:2002E0006F10E9C1AFC93EFFC1C93E0DCD6703E5214604CD5403E17CCD1B037DCD1B033EB2
:2003000020CD6703CD670306107E23CD1B033E20CD670310F43E0DCD6703C9F50F0F0F0F98
:20032000CD4803CD6703F1CD4803CD6703C9D6303813FE0A380ED611FE063806D620FE06A3
:200340003003C60AC93EFFC9E60FFE0A3803C637C9C630C97EFE00C8CD67032318F6DB8502
:20036000CB4728FADB84C9F5DB85CB5728FAF1D384C9060B0E8721B703EDB306090E852193
:20038000AE03EDB3C93E00D3893ECFD3893E0FD3893E07D3893EFFD3893E00D38B3ECFD3E1
:2003A0008B3EFFD38B3E07D38B3EFFD38BC918144403C105681100180200144403C10568BB
:2003C00011004D6F6E69746F72205A38302B53494F2B50494F20766572302E373120206244
:2003E000792050696E65636F6E6520323032302F30392F30320D000D3F2048656C700D64B3
:20040000204D656D6F727944756D700D6D204D656D6F72794368616E67650D6C2048657896
:2004200046696C654C6F61640D6A206A756D700D6920492F6F52656769737465720D632017
:2004400043616C6C0D006164647220202B30202B31202B32202B33202B34202B35202B36E6
:1D046000202B37202B38202B39202B41202B42202B43202B44202B45202B460D0092
:00000001FF

最初のモニタが起動できたので、次回はROMからRAMに切り替え64KフルRAMになるか確認したいと思います。

おすすめの記事