実際にシリアル通信のプログラムを作成していきたいと思います。

条件として、ボーレート38400bps(システムクロック19.6608MHz使用時)、8bitキャラクター、1ストップビット、ノンパリティーの設定(81N)で通信を行います。
また、cポートのRxA(PC7-51pin)/TxA(PC6-54pin)を使用します。

レジスタを定義します。
新たに、ポートcポート、タイマーA、シリアルポート関連のレジスタを追加

;;Parallel ports 
;;PPC
;;Port C Data Ragister
PCDR	.equ	0x50
;;Port C Function Ragister
PCFR	.equ	0x55


;;Timer A
;;Timer A Control/Status Register
TACSR	.equ	0xa0
;;Timer A Control Register
TACR	.equ	0xa4
;;Timer A1 Constant register
TAT1R	.equ	0xA3
;;Timer A4 Constant register
TAT4R	.equ	0xA9

;;Serial A port
;;Serial A Port Status Register
SASR	.equ	0xc3
;;Serial A port Control Register
SACR	.equ	0xc4
;;Serial A port Data Register
SADR	.equ	0xc0
;;Serial A port Long Register
SALR	.equ	0xc2

タイマーAを有効にします。
タイマーA4のクロック入力をPCLK/2に、割り込みを無効にします
タイマーA4のシリアルクロックの分周値を設定します。

	ld	a,0x01			;PCLK/2 Timer A Enabled
	ioi ld	(TACSR),a
	ld	a,0b00000000		;Timer A4~A7 Clocked by PCLK/2,interrupts disabled
	ioi ld	(TACR),a
	ld	a,0x0f			;A-ch Clock timer :=(PCLK/2/16/38400)-1 (PCLK=19.6608MHz >> 38400bps)
	ioi ld	(TAT4R),a

パラレルポートの初期化をします。
ここでは、Cポートのシリアル端子を有効にします。

ppinit:
	ld	a,0x40
	ioi ld	(PCFR),a		;C Port TxA set
	ret

シリアルポートの初期化をします。
非同期モード、Cポートを使用、8bitキャラクタ、割り込みを無効

sioinit:
	ld	a,0b00000000
	ioi ld	(SACR),a		;Asynch mode, C port used, 8bit, Interrupt Disabled
	ret

1文字出力ルーチン
ステータスレジスタSASRの3bit目を確認します。
送信バッファーが空になるまでループ待ちします。
送信データを書き込みします。
送信バッファーが空になるまでループ待ちします。

putchar:				
	push	af
putchar01:
	ioi ld	a,(SASR)		;Serial A port Status in
      	bit     3,a			
        jr      nz,putchar01		;XMIT DATA REG > Full(bit3==1) check
 	pop	af
 	push	af
	ioi ld	(SADR),a		;no full(Empty) >> TxA data out
putchar_busy:
	ioi ld	a,(SASR)		;Serial A port Status in
	bit	3,a			;XMIT DATA REG > Full(bit3==1) check 
	jr	nz,putchar_busy
	pop	af			;no full(Empty) >> return
	ret

1文字入力ルーチン
ステータスレジスタSASRの7bit目を確認します。
受信バッファーにデータが来るまでループ待ちします。
受信データを読み込みします。
受信バッファーが空になるまでループ待ちします。

getchar:
	ioi ld 	a,(SASR)		;Serial A port Status in
	bit	7,a			;RCV DATA REG > EMPTY(bit7==0) check
	jr	z,getchar
	ioi ld	a,(SADR)		;No EMPTY(Full) > RxA data in
	push	af
getchar01:
	ioi ld	a,(SASR)		;Serial A port Status in
	bit	7,a			;RCV DATA REG >EMPTY(bit7==0) check
	jr	nz,getchar01
	pop	af			;EMPTY >> return
	ret


動作確認用プログラムは、リセット後、改行したのち”OK”の表示し、再度改行したのち、”>”の表示に続いて入力された文字をエコーバックします。

	ld	a,0x0d
	call	putchar
	ld	a,'O
	call	putchar
	ld	a,'K
	call	putchar
	ld	a,0x0d
	call	putchar
	ld	a,'>
	call	putchar
loop:
	call	getchar
	call	putchar
	jr	loop

以下プログラム全体です。

; rabbit2000 serial communication test (A ch)
;
; rabbit2000 cpu
; rom 0000h -- 7fffh
; ram 8000h -- ffffh
; External clock 19.6608MHz

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

       .r2k

        .area TEST(ABS)


;;Global Control/Status Register
GCSR	.equ	0x00
;;Global Output Control Register
GOCR	.equ	0x0e
;;MMU: Memory Bank 0 Control Ragister
MB0CR	.equ	0x14
;;MMU: Memory Bank 1 Control Ragister
MB1CR	.equ	0x15
;;MMU: MMU Instruction/Data Register
MMIDR	.equ	0x10
;;MMU: Data Segment Register(Z180 BBR)
DATASEG	.equ	0x12
;;MMU: Segment Size Register(Z180 CBAR)
SEGSIZE	.equ	0x13
;;MMU: Stack Segment Register(Z180 CBR)
STACKSEG	.equ	0x11


;;Parallel ports 
;;PPC
;;Port C Data Ragister
PCDR	.equ	0x50
;;Port C Function Ragister
PCFR	.equ	0x55


;;Timer A
;;Timer A Control/Status Register
TACSR	.equ	0xa0
;;Timer A Control Register
TACR	.equ	0xa4
;;Timer A1 Constant register
TAT1R	.equ	0xA3
;;Timer A4 Constant register
TAT4R	.equ	0xA9

;;Serial A port
;;Serial A Port Status Register
SASR	.equ	0xc3
;;Serial A port Control Register
SACR	.equ	0xc4
;;Serial A port Data Register
SADR	.equ	0xc0
;;Serial A port Long Register
SALR	.equ	0xc2


	.org	0x0000
	
		jp	start
		
	.org	0x0080

start:

	ld	a,0b00001000		;proc=OSC,pclk=osc,periodic interrupt=disable
	ioi ld	(GCSR),a
	ld	a,0x00			;0x000000 Use /OE0 or /WE0 Use CS0
	ioi ld	(MB0CR),a		;use ROM
	ld	a,0b00000101		;0x400000 Use /OE1 or /WE1 Use CS1
	ioi ld	(MB1CR),a		;use RAM
;
	ld	a,0x01			;PCLK/2 Timer A Enabled
	ioi ld	(TACSR),a
	ld	a,0b00000000		;Timer A4~A7 Clocked by PCLK/2,interrupts disabled
	ioi ld	(TACR),a
	ld	a,0x0f			;A-ch Clock timer :=(PCLK/2/16/38400)-1 (PCLK=19.6608MHz >> 38400bps)
	ioi ld	(TAT4R),a

	ld	a,0x40			;MMU Data Reg Physics address 0x40000 (CS1)
	ioi ld	(DATASEG),a
	ld	a,0x40			;MMU Stack Reg Physics address 0x40000 (CS1)
	ioi ld 	(STACKSEG),a
	ld	a,0xa8			;MMU Segsize logic Data address 0x8000 (CS1:0x48000)
	ioi ld	(SEGSIZE),a		;MMU Segsize logic Stack address 0xa000 (CS1:0x4a000)
	
	ld	a,0x40			;MMU XPC Physics address 0x40000 (CS1:0x4e000)
	ld	xpc,a
	
	jp	main

        .org    0x0100
main:
	ld	sp,0xe000		;stack pointer set

	call	ppinit			;parallel ports initialize
	call	sioinit			;serial channel initialize

	ld	a,0x0d
	call	putchar
	ld	a,'O
	call	putchar
	ld	a,'K
	call	putchar
	ld	a,0x0d
	call	putchar
	ld	a,'>
	call	putchar
loop:
	call	getchar
	call	putchar
	jr	loop
	
ppinit:
	ld	a,0x40
	ioi ld	(PCFR),a		;C Port TxA set
	ret
sioinit:
	ld	a,0b00000000
	ioi ld	(SACR),a		;Asynch mode, C port used, 8bit, Interrupt Disabled
	ret

putchar:				
	push	af
putchar01:
	ioi ld	a,(SASR)		;Serial A port Status in
      	bit     3,a			
        jr      nz,putchar01		;XMIT DATA REG > Full(bit3==1) check
 	pop	af
 	push	af
	ioi ld	(SADR),a		;no full(Empty) >> TxA data out
putchar_busy:
	ioi ld	a,(SASR)		;Serial A port Status in
	bit	3,a			;XMIT DATA REG > Full(bit3==1) check 
	jr	nz,putchar_busy
	pop	af			;no full(Empty) >> return
	ret
	
getchar:
	ioi ld 	a,(SASR)		;Serial A port Status in
	bit	7,a			;RCV DATA REG > EMPTY(bit7==0) check
	jr	z,getchar
	ioi ld	a,(SADR)		;No EMPTY(Full) > RxA data in
	push	af
getchar01:
	ioi ld	a,(SASR)		;Serial A port Status in
	bit	7,a			;RCV DATA REG >EMPTY(bit7==0) check
	jr	nz,getchar01
	pop	af			;EMPTY >> return
	ret
	
	.end

HEXファイルです。

:03000000C38000BA
:200080003E08D33200003E00D33214003E05D33215003E01D332A0003E00D332A4003E0F49
:1D00A000D332A9003E40D33212003E40D33211003EA8D33213003E40ED67C30001D8
:200100003100E0CD2A01CD31013E0DCD38013E4FCD38013E4BCD38013E0DCD38013E3ECDCA
:200120003801CD5101CD380118F83E40D3325500C93E00D332C400C9F5D33AC300CB5F20D1
:20014000F8F1F5D332C000D33AC300CB5F20F8F1C9D33AC300CB7F28F8D33AC000F5D33A27
:08016000C300CB7F20F8F1C9B8
:00000001FF

次回は、”最初のモニタ”を移植していきたいと思います。

コメントを残す

  • Z80(Rabbit2000)に萌えたい。9-クロックとモニタの改善
  • Z80(Rabbit2000)に萌えたい。8-最初のモニタその2
  • Z80(Rabbit2000)に萌えたい。7-最初のモニタその1
  • Z80(Rabbit2000)に萌えたい。6-シリアル通信その2
  • Z80(Rabbit2000)に萌えたい。5-シリアル通信その1
  • Z80(Rabbit2000)に萌えたい。4-RAM動作確認
おすすめの記事
Z8S180
I2C通信が行えるようにZ8S180にパラレル-I2C変換用IC PCA9564Dを接続したいと思います。 なお、PCA9564Dは以前、Z...
BIOS
ちょっとだけ、BIOSの移植が進んだのでメモしたいと思います。 BIOSを移植するにあたり、実機での確認が不可欠と思いますが、それを行うには...