石原 博の覚書

電子工作に関する日々の覚書を記載します

KBC-Z84015EM ForthでLチカ

2021-12-05 17:51:27 | 日記

デジット閉店セールで売られていたジャンク基板「KBC-Z84015EM」でForthを動かした。

該当の基板では前半32KBはROM,後半32KBはRAMとなっているが、fig-forthやf79, f83はRAM上で動くことを想定している。ForthをROM化する能力も時間もないので、起動時にROM中に保存したForthシステムをRAMにコピーする方式とした。I/Oについては電脳伝説さんのサイト「https://vintagechips.wordpress.com/2021/06/08/kbc-z84015s/」を参考にSIOを利用。DISK I/Oはエラーとなるようにしている。

最初はF83と思ったが、08000H開始でメタコンパイルする方法がわからない。そこで移植したのはfig-forth(ASMだけでアセンブル出来るから楽)。 サイト(https://www.complang.tuwien.ac.at/forth/ftp.dei.isep.ipp.pt/pub/forth/cpm/forth130.asm)からFig-forth1.3のソースをダウンロード。(このForthどうもAppleII用のZ80カードを対象としていたものか、APPLE EQU TRUEなどとの記載がある) TITLEとかPAGE等の疑似命令がエラーになるので修正し ORG 100H -> ORG 08100H, EM EQU 0A000H -> EM EQU 0C000H としてアセンブルしてHexファイルを作る。

I/O部分についてはSTARTUP.ASMとして以下のように作成。プログラムは100H〜で、8000Hをワークとしている。 ロジックは電脳伝説さんのサイトのBASICのI/O部分を使用させていただいた。PIOの初期化も組み込んでいる。なおニーモニックはインテルのものに変更しているが、これは私がその方がわかりやすかったためで他意はない。ForthはROM上400H〜に保存しておき、起動時に8100Hにコピーして制御を移すようにしている。



;	TARGET: KBC-Z84015S
;
TSTACK	EQU	0H
;
;PCTCC0	EQU	10H
;PCTCC1	EQU	11H
PCTCC2	EQU	12H
;PCTCC3	EQU	13H
PSIOAD	EQU	18H
PSIOAC	EQU	19H
PSIOBD	EQU	1AH
PSIOBC	EQU	1BH
;PPIOAD	EQU	1CH
;PPIOAC	EQU	1DH
PPIOBD	EQU	1EH
PPIOBC	EQU	1FH
;
CR	EQU	0DH
LF	EQU	0AH
;
ROMST	EQU	400H		; ROM CONTENTS START
ROMSIZE	EQU	2000H		; ROM SIZE
RAMST	EQU	8000H		; RAM START
FORTHST EQU	8100H
;
;	SYSTEM PARAMETERS
	ORG	RAMST
RBFCNT	DS	01H
RBFRDP	DS	01H
RBFWTP	DS	01H
RECBUF	DS	40H
;
;
;	RESET VECTOR
	ORG	0000H
RST00:	;DI
	JMP	BIOS		;PSEUDO BIOS
;
;	RESTART VECTOR
	ORG	0008H
RST08:	JMP	TXA
	ORG	0010H
RST10:	JMP	RXA
	ORG	0018H
RST18:	JMP	KBHIT
;
	ORG	0100H
BIOS:
	JMP	SINIT		;0
	JMP	CONST		;3
	JMP	CONIN		;6
	JMP	CONOUT		;9
	JMP	LIST		;12
	JMP	ERROR		;15
	JMP	ERROR		;18
	JMP	ERROR		;21
	JMP	ERROR		;24
	JMP	ERROR		;27
	JMP	ERROR		;30
	JMP	ERROR		;33
	JMP	ERROR		;36
	JMP	ERROR		;39
;
CONST:	CALL	KBHIT		;A=COUNT
	RZ
	MVI	A,0FFH
	RET
;
CONIN:	CALL	RXA		;RETURN CHARACTER IN A
	ANI	07FH
	RET
;
CONOUT:	MOV	A,C		;WRITE CHARACTER IN C
	ANI	07FH
	JMP	TXA
;
LIST:	RET			;NOT SUPPORTED
;
ERROR:	LXI	H,ERRMSG
ERROR1:	MOV	A,M
	INX	H
	ANA	A
	JZ	BIOS
	CALL	TXA
	JMP	ERROR1
;
ERRMSG:	DB	'ILLEGAL ',CR,LF,0
;
;	SIOA -> BUFFER BY INTERRUPT
INTRCV:
	PUSH	PSW
	PUSH	B
	PUSH	D
	PUSH	H
	IN	PSIOAC		;CHECK RECEIVE
	ANI	1		;IF NOT
	JZ	RWTEXT		;EXIT
	IN	PSIOAD		;GET DATA
	MOV	D,A		;SAVE TO D
	LDA	RBFCNT		;GET COUNT
	CPI	40H		;IF BUFFER FULL
	JZ	RWTEXT		;EXIT(GIVE UP)
STRWT3:	INR	A		;COUNT UP
	STA	RBFCNT		;COUNT UPDATE
	LDA	RBFWTP		;GET OFFSET
	MOV	C,A		;C, OFFSET LOW
	MVI	B,00H		;B, OFFSET HIGH
	LXI	H,RECBUF	;HL, BUFFER TOP
	DAD	B		;HL, WRITE POINT IN BUFFER
	MOV	M,D		;WRITE DATA
	INR	A		;OFFSET INCREMENT
	ANI	3FH		;WRAP
	STA	RBFWTP		;OFFSET UPDATE
RWTEXT:	POP	H
	POP	D
	POP	B
	POP	PSW
	EI
	DB	0EDH,4DH	;RETI
;
;	BUFER -> A
RXA:
	PUSH	B
	PUSH	D
	PUSH	H
LOPRBR:
	LDA	RBFCNT		;GET COUNT
	ANA	A		;CHECK RECEIVE
	JZ	LOPRBR		;WAIT FOR RECEIVE
	DI			;DISABLE INTERRUPT
	DCR	A		;COUNT DOWN
	STA	RBFCNT		;COUNT UPDATE
	LDA	RBFRDP		;GET OFFSET
	MOV	C,A		;C, OFFSET LOW
	MVI	B,00H		;B, OFFSET HIGH
	LXI	H,RECBUF	;HL, BUFFER TOP
	DAD	B		;HL, READ POINT IN BUFFER
	MOV	D,M		;READ DATA
	INR	A		;OFFSET INCREMENT
	ANI	3FH		;WRAP
	STA	RBFRDP		;OFFSET UPDATE
	MOV	A,D		;GET DATA
	EI			;ENABLE INTERRUPT
	POP	H
	POP	D
	POP	B
	RET
;
;	A -> SIO
TXA:	PUSH	PSW		;SAVE DATA
TXLOOP:	IN	PSIOAC		;CHECK STATUS
	ANI	4		;IF BUFFER NOT EMPTY
	JZ	TXLOOP		;WAIT FOR EMPTY
	POP	PSW		;RESTORE DATA
	OUT	PSIOAD		;TRANSFER
	RET
;
;	CHECK RECEIVE STATUS
KBHIT:	LDA	RBFCNT
	ANA	A
	RET
;
;	INTERRUPT VECTORS
	ORG (($-1) AND 0FFF0H) + 10H
INTVCT:	DW	INTRCV
;
;	SIOA COMMAND CHAIN
SIOACD:
	DB	00011000B	;RESET
	DB	01H,00010000B	;RX INTERRUPT ENABLE
	DB	04H,01000100B	;FORMAT
	DB	05H,11101010B	;TX ENABLE
	DB	03H,11000001B	;RX ENABLE
SIOACL	EQU	$-SIOACD
;
;	SIOB COMMAND CHAIN
SIOBCD:
	DB	00011000B		;RESET
	DB	01H,00000000B		;DISABLE STATUS/AFFECTS VECTOR
	DB	02H,INTVCT AND 00FFH	;SET INTERRUPT VECTOR
SIOBCL	EQU	$-SIOBCD
;
;	PIOB COMMAND CHAIN
PIOBCD:
	DB	0CFH			;MODE3
	DB	9FH			;PB5,PB6 OUT
	DB	07H			;INTERRUPT DISABLE
PIOBCL	EQU	$-PIOBCD
;
;	SYSTEM INITIALIZE
SINIT:	LXI	SP,TSTACK
	XRA	A
	STA	RBFCNT
	STA	RBFRDP
	STA	RBFWTP
;
;	CTC INITIALIZE
	MVI	A,01010111B
	OUT	PCTCC2
	MVI	A,20		;9600bps@6.144MHz
	OUT	PCTCC2
;
;	SIO INITIALIZE
	MVI	B,SIOACL	;LENGTH
	LXI	H,SIOACD	;COMMAND ADDRESS
SIOA:	MOV	A,M
	INX	H
	OUT	PSIOAC		;I/O ADDRESS
	DCR	B
	JNZ	SIOA	
	MVI	B,SIOBCL	;LENGTH
	LXI	H,SIOBCD	;COMMAND ADDRESS
SIOB:	MOV	A,M
	INX	H
	OUT	PSIOBC		;I/O ADDRESS
	DCR	B
	JNZ	SIOB
;
;	PIO INITIALIZE
	MVI	B,PIOBCL	;LENGTH
	LXI	H,PIOBCD	;COMMAND ADDRESS
PIOB:	MOV	A,M
	INX	H
	OUT	PPIOBC		;I/O ADDRESS
	DCR	B
	JNZ	PIOB
;
;	SETUP INTERRUPT
	LXI	H,INTVCT
	MOV	A,H
	DB	0EDH,47H	;LD	I,A
	DB	0EDH,5EH	;IM	2
	EI
;
;	COPY ROMPG TO RAM
	LXI	H,ROMST
	LXI	D,FORTHST
	LXI	B,ROMSIZE
COPY1:	MOV	A,M
	INX	H
	STAX	D
	INX	D
	DCX	B
	MOV	A,B
	ORA	C
	JNZ	COPY1
	JMP	FORTHST

ASMでアセンブルし、SETUP.HEXとFORTH130.HEXの両者をTL866AでROMに書き込み実行。使用したROMはW27C512(64KB)のため有効なのは8000〜FFFF。そのため書き込みは工夫が必要。

SETUP.HEX は

From File Start Addr 0 
TO Buffer Start Addr 8000 
Clear Buffer when loading the file->Clear Buffer with defalult 
FORTH130.HEXは

From File Start Addr 8100 
TO Buffer Start Addr 8400 
Clear Buffer when loading the file->Disable 

としてTL866Aのバッファー領域に両方のHexファイルを読み込んだあと焼き込む。

注意点

[1]ジャンパの設定
この基板はRAMは32KBのHM62256が使用されているが、ジャンパの設定で8KB(8000H〜9FFFH)のみが有効。Fig-Forthはちょうど8KBに収まるのだが、SETUP.ASMで入力用のバッファを使うためほんの少し8KBを超える。そこでジャンパJ2を変更して32KBを有効にした。最初これを忘れて動かず悩んだ。

[2]CONIN, CONOUTではパリティのクリアが必要
最初bit7を気にしていなかったが、Fig-ForthでVLISTするとワードの最後の文字が化けた。(Fig-Forthではワード名の最後のbit7が1になっている) CP/Mマニュアルでは、CONIN 「parity bit is set to zero」 CONOUT「high-order parity bit set to zero」となっており、SETUP.ASM内でbit7を0とするようにした。

これにより以下のLチカが動くことが確認出来た。

===================

HEX OK 
: LED_ON 0 1E P! ; OK 
: LED_OFF FF 1E P! ; OK 
: WAIT 1000 0 DO LOOP ; OK 
: TEST 0 DO LED_ON WAIT LED_OFF WAIT LOOP ; OK 
10 TEST OK


最新の画像もっと見る

コメントを投稿