実際にシリアル通信のプログラムを作成していきたいと思います。
条件として、ボーレート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
次回は、”最初のモニタ”を移植していきたいと思います。