前回の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になるか確認したいと思います。