前回ソフトウエアUARTで、受信ではインタラプトを利用していたが、単純化のためポーリングで出来るかどうか実験した。
40年ほど昔、学生時代にMZ80Bを購入してモニタを自作しCP/Mを移植したことがあるが、
入力ルーチンでソフトウエアでキーボードをスキャンしコード化しており、インタラプトなど使っていなかった。
人がプロンプトが出てから入力するならば不要と言える。
ただシリアルは人のキーボード入力に比べれば、遥かに速くタイミングがずれると文字化けする。
CP/MではCONSTがキー入力の有無を調べるルーチンであるが、どれくらいの頻度・タイミングで呼び出されるのかはアプリ次第。
仕方ないので少々応答性は犠牲にして、CONST相当のルーチンが呼び出された場合は100回程度(適当)ポーリングし、その間にキー入力がなければ
キー入力なしとしてリターン。あればコードを保存後にキー入力ありとしてリターンする。
という手段を使用した。
これでインタラプトを使用しない入力が出来て、FigForthと組み合わせることで動作確認出来た。
(PPADのbit0がRX、bit1がTX相当)
なおFigForthは前回同様 08100H〜の領域にアセンブルし、ROMには0400H〜に書き込んでいる。
; soft uart
0000 = TSTACK EQU 0H
;
0054 = PPAC EQU 54H
;PPBC EQU 55H
;PPCC EQU 56H
;PPDC EQU 34H
;PPEC EQU 44H
0050 = PPAD EQU 50H
;PPBD EQU 51H
;PPCD EQU 52H
;PPDD EQU 30H
;PPED EQU 40H
8000 = RAMST EQU 8000H ; RAM START
000D = CR EQU 0DH
000A = LF EQU 0AH
;
0400 = ROMST EQU 400H ; ROM CONTENTS START
2000 = ROMSIZE EQU 2000H ; ROM SIZE
8000 = RAMST EQU 8000H ; RAM START
8000 = CHARBUF EQU 8000H
8100 = FORTHST EQU 8100H
;
0000 ORG 0H
0000 C30001 JMP 100H
;
0100 ORG 100H
BIOS:
0100 C32A01 JMP SINIT ;0
0103 C3DC01 JMP CONST ;3
0106 C3E301 JMP CONIN ;6
0109 C3FB01 JMP CONOUT ;9
010C C30102 JMP LIST ;12
010F C35101 JMP ERROR ;15
0112 C35101 JMP ERROR ;18
0115 C35101 JMP ERROR ;21
0118 C35101 JMP ERROR ;24
011B C35101 JMP ERROR ;27
011E C35101 JMP ERROR ;30
0121 C35101 JMP ERROR ;33
0124 C35101 JMP ERROR ;36
0127 C35101 JMP ERROR ;39
;
; SYSTEM INITIALIZE
012A 310000 SINIT: LXI SP,TSTACK
012D AF XRA A
012E 320080 STA CHARBUF
;
; Z84C011 PORT I/O INITIALIZE
0131 3E01 MVI A,00000001B ;OUT=1, IN=0
0133 D354 OUT PPAC ;PORT0 OUT, PORT1 IN
0135 DB50 IN PPAD
0137 F601 ORI 1 ;INITIAL
0139 D350 OUT PPAD
;
; COPY ROMPG TO RAM
013B 210004 LXI H,ROMST
013E 110081 LXI D,FORTHST
0141 010020 LXI B,ROMSIZE
0144 7E COPY1: MOV A,M
0145 23 INX H
0146 12 STAX D
0147 13 INX D
0148 0B DCX B
0149 78 MOV A,B
014A B1 ORA C
014B C24401 JNZ COPY1
014E C30081 JMP FORTHST
;
0151 216001 ERROR: LXI H,ERRMSG
0154 7E ERROR1: MOV A,M
0155 23 INX H
0156 A7 ANA A
0157 CA0001 JZ BIOS
015A CD6B01 CALL OUTCH
015D C35401 JMP ERROR1
;
0160 494C4C4547ERRMSG: DB 'ILLEGAL ',CR,LF,0
;
016B F5 OUTCH: PUSH PSW
016C DB50 IN PPAD
016E E6FE ANI 0FEH ;START BIT
0170 D350 OUT PPAD
0172 CDCA01 CALL WAIT
0175 F1 POP PSW
0176 D5 PUSH D
0177 C5 PUSH B
0178 0608 MVI B,8
017A 4F OUTCH1: MOV C,A
017B E601 ANI 1 ;BIT0
017D 57 MOV D,A
017E DB50 IN PPAD
0180 E6FE ANI 0FEH
0182 B2 ORA D
0183 D350 OUT PPAD
0185 CDCA01 CALL WAIT
0188 79 MOV A,C
0189 0F RRC
018A 05 DCR B
018B C27A01 JNZ OUTCH1
018E DB50 IN PPAD
0190 F601 ORI 1 ;STOP BIT
0192 D350 OUT PPAD
0194 CDCA01 CALL WAIT
0197 C1 POP B
0198 D1 POP D
0199 C9 RET
;
019A C5 KBHIT: PUSH B
019B 0664 MVI B,100
019D DB50 KBHIT1: IN PPAD ;START BIT CHECK
019F E602 ANI 2
01A1 CAAB01 JZ KBHIT2
01A4 05 DCR B
01A5 C29D01 JNZ KBHIT1
01A8 C1 POP B
01A9 AF XRA A
01AA C9 RET
01AB CDD301 KBHIT2: CALL WAITS ;SKIP START BIT(HALF)
01AE 010008 LXI B,0800H ;B=8,C=0
01B1 CDCA01 KBHIT3: CALL WAIT
01B4 DB50 IN PPAD
01B6 E602 ANI 2
01B8 0F RRC
01B9 B1 ORA C
01BA 05 DCR B
01BB CAC301 JZ KBHIT4
01BE 0F RRC
01BF 4F MOV C,A
01C0 C3B101 JMP KBHIT3
01C3 0F KBHIT4: RRC ;B6,B5,B4,B3,B2,B1,B0,B7->B7..B0
01C4 A7 ANA A
01C5 320080 STA CHARBUF
01C8 C1 POP B
01C9 C9 RET
;
01CA C5 WAIT: PUSH B ;11+7+(4+10)*N+10+10=38+14*N 6MHz
01CB 0625 MVI B,37 ;N=37 -> 93E-6SEC
01CD 05 WAIT1: DCR B
01CE C2CD01 JNZ WAIT1
01D1 C1 POP B
01D2 C9 RET
;
01D3 C5 WAITS: PUSH B ;11+7+(4+10)*N+10+10
01D4 060D MVI B,13 ;N=13 -> 37E-6SEC
01D6 05 WAITS1: DCR B
01D7 C2D601 JNZ WAITS1
01DA C1 POP B
01DB C9 RET
;
01DC CD9A01 CONST: CALL KBHIT ;A=COUNT
01DF C8 RZ
01E0 3EFF MVI A,0FFH
01E2 C9 RET
;
01E3 3A0080 CONIN: LDA CHARBUF ;RETURN CHARACTER IN A
01E6 E67F ANI 07FH
01E8 CAF201 JZ CONIN1
01EB F5 PUSH PSW
01EC AF XRA A
01ED 320080 STA CHARBUF
01F0 F1 POP PSW
01F1 C9 RET
01F2 CDDC01 CONIN1: CALL CONST
01F5 CAF201 JZ CONIN1
01F8 C3E301 JMP CONIN
;
01FB 79 CONOUT: MOV A,C ;WRITE CHARACTER IN C
01FC E67F ANI 07FH
01FE C36B01 JMP OUTCH
;
0201 C9 LIST: RET ;NOT SUPPORTED
40年ほど昔、学生時代にMZ80Bを購入してモニタを自作しCP/Mを移植したことがあるが、
入力ルーチンでソフトウエアでキーボードをスキャンしコード化しており、インタラプトなど使っていなかった。
人がプロンプトが出てから入力するならば不要と言える。
ただシリアルは人のキーボード入力に比べれば、遥かに速くタイミングがずれると文字化けする。
CP/MではCONSTがキー入力の有無を調べるルーチンであるが、どれくらいの頻度・タイミングで呼び出されるのかはアプリ次第。
仕方ないので少々応答性は犠牲にして、CONST相当のルーチンが呼び出された場合は100回程度(適当)ポーリングし、その間にキー入力がなければ
キー入力なしとしてリターン。あればコードを保存後にキー入力ありとしてリターンする。
という手段を使用した。
これでインタラプトを使用しない入力が出来て、FigForthと組み合わせることで動作確認出来た。
(PPADのbit0がRX、bit1がTX相当)
なおFigForthは前回同様 08100H〜の領域にアセンブルし、ROMには0400H〜に書き込んでいる。
; soft uart
0000 = TSTACK EQU 0H
;
0054 = PPAC EQU 54H
;PPBC EQU 55H
;PPCC EQU 56H
;PPDC EQU 34H
;PPEC EQU 44H
0050 = PPAD EQU 50H
;PPBD EQU 51H
;PPCD EQU 52H
;PPDD EQU 30H
;PPED EQU 40H
8000 = RAMST EQU 8000H ; RAM START
000D = CR EQU 0DH
000A = LF EQU 0AH
;
0400 = ROMST EQU 400H ; ROM CONTENTS START
2000 = ROMSIZE EQU 2000H ; ROM SIZE
8000 = RAMST EQU 8000H ; RAM START
8000 = CHARBUF EQU 8000H
8100 = FORTHST EQU 8100H
;
0000 ORG 0H
0000 C30001 JMP 100H
;
0100 ORG 100H
BIOS:
0100 C32A01 JMP SINIT ;0
0103 C3DC01 JMP CONST ;3
0106 C3E301 JMP CONIN ;6
0109 C3FB01 JMP CONOUT ;9
010C C30102 JMP LIST ;12
010F C35101 JMP ERROR ;15
0112 C35101 JMP ERROR ;18
0115 C35101 JMP ERROR ;21
0118 C35101 JMP ERROR ;24
011B C35101 JMP ERROR ;27
011E C35101 JMP ERROR ;30
0121 C35101 JMP ERROR ;33
0124 C35101 JMP ERROR ;36
0127 C35101 JMP ERROR ;39
;
; SYSTEM INITIALIZE
012A 310000 SINIT: LXI SP,TSTACK
012D AF XRA A
012E 320080 STA CHARBUF
;
; Z84C011 PORT I/O INITIALIZE
0131 3E01 MVI A,00000001B ;OUT=1, IN=0
0133 D354 OUT PPAC ;PORT0 OUT, PORT1 IN
0135 DB50 IN PPAD
0137 F601 ORI 1 ;INITIAL
0139 D350 OUT PPAD
;
; COPY ROMPG TO RAM
013B 210004 LXI H,ROMST
013E 110081 LXI D,FORTHST
0141 010020 LXI B,ROMSIZE
0144 7E COPY1: MOV A,M
0145 23 INX H
0146 12 STAX D
0147 13 INX D
0148 0B DCX B
0149 78 MOV A,B
014A B1 ORA C
014B C24401 JNZ COPY1
014E C30081 JMP FORTHST
;
0151 216001 ERROR: LXI H,ERRMSG
0154 7E ERROR1: MOV A,M
0155 23 INX H
0156 A7 ANA A
0157 CA0001 JZ BIOS
015A CD6B01 CALL OUTCH
015D C35401 JMP ERROR1
;
0160 494C4C4547ERRMSG: DB 'ILLEGAL ',CR,LF,0
;
016B F5 OUTCH: PUSH PSW
016C DB50 IN PPAD
016E E6FE ANI 0FEH ;START BIT
0170 D350 OUT PPAD
0172 CDCA01 CALL WAIT
0175 F1 POP PSW
0176 D5 PUSH D
0177 C5 PUSH B
0178 0608 MVI B,8
017A 4F OUTCH1: MOV C,A
017B E601 ANI 1 ;BIT0
017D 57 MOV D,A
017E DB50 IN PPAD
0180 E6FE ANI 0FEH
0182 B2 ORA D
0183 D350 OUT PPAD
0185 CDCA01 CALL WAIT
0188 79 MOV A,C
0189 0F RRC
018A 05 DCR B
018B C27A01 JNZ OUTCH1
018E DB50 IN PPAD
0190 F601 ORI 1 ;STOP BIT
0192 D350 OUT PPAD
0194 CDCA01 CALL WAIT
0197 C1 POP B
0198 D1 POP D
0199 C9 RET
;
019A C5 KBHIT: PUSH B
019B 0664 MVI B,100
019D DB50 KBHIT1: IN PPAD ;START BIT CHECK
019F E602 ANI 2
01A1 CAAB01 JZ KBHIT2
01A4 05 DCR B
01A5 C29D01 JNZ KBHIT1
01A8 C1 POP B
01A9 AF XRA A
01AA C9 RET
01AB CDD301 KBHIT2: CALL WAITS ;SKIP START BIT(HALF)
01AE 010008 LXI B,0800H ;B=8,C=0
01B1 CDCA01 KBHIT3: CALL WAIT
01B4 DB50 IN PPAD
01B6 E602 ANI 2
01B8 0F RRC
01B9 B1 ORA C
01BA 05 DCR B
01BB CAC301 JZ KBHIT4
01BE 0F RRC
01BF 4F MOV C,A
01C0 C3B101 JMP KBHIT3
01C3 0F KBHIT4: RRC ;B6,B5,B4,B3,B2,B1,B0,B7->B7..B0
01C4 A7 ANA A
01C5 320080 STA CHARBUF
01C8 C1 POP B
01C9 C9 RET
;
01CA C5 WAIT: PUSH B ;11+7+(4+10)*N+10+10=38+14*N 6MHz
01CB 0625 MVI B,37 ;N=37 -> 93E-6SEC
01CD 05 WAIT1: DCR B
01CE C2CD01 JNZ WAIT1
01D1 C1 POP B
01D2 C9 RET
;
01D3 C5 WAITS: PUSH B ;11+7+(4+10)*N+10+10
01D4 060D MVI B,13 ;N=13 -> 37E-6SEC
01D6 05 WAITS1: DCR B
01D7 C2D601 JNZ WAITS1
01DA C1 POP B
01DB C9 RET
;
01DC CD9A01 CONST: CALL KBHIT ;A=COUNT
01DF C8 RZ
01E0 3EFF MVI A,0FFH
01E2 C9 RET
;
01E3 3A0080 CONIN: LDA CHARBUF ;RETURN CHARACTER IN A
01E6 E67F ANI 07FH
01E8 CAF201 JZ CONIN1
01EB F5 PUSH PSW
01EC AF XRA A
01ED 320080 STA CHARBUF
01F0 F1 POP PSW
01F1 C9 RET
01F2 CDDC01 CONIN1: CALL CONST
01F5 CAF201 JZ CONIN1
01F8 C3E301 JMP CONIN
;
01FB 79 CONOUT: MOV A,C ;WRITE CHARACTER IN C
01FC E67F ANI 07FH
01FE C36B01 JMP OUTCH
;
0201 C9 LIST: RET ;NOT SUPPORTED
※コメント投稿者のブログIDはブログ作成者のみに通知されます