Notiz: Ein Terminal (Zterm) benutzen um Textfiles an das amforth zu senden.
Im amforth dienen rx0
und tx0
als key
und emit
. Dabei sind rx0
und tx0
interruptgetrieben und benutzten einen Ringpuffer um schnelleres I/O zu bieten. Aber einige Terminals konnten schlecht Schritt halten mit dieser Art Pufferung sobald man versuchte Textdateien zu senden anstatt die Zeichen von Hand einzutippen. Zeichen gingen verloren und es gab immer wieder Pufferüberläufe.
Im Zterm kann eine spezielle Art von Synchronisation mit dem Empfänger ausgewählt werden, das „text pacing“ durch „wait for character echo“; was soviel heißt wie „Schrittmacher ist das Echo des Zeichens.“ Das funktionierte am besten ganz ohne Interrupts. Wenn key
und emit
einfach nachschauten ob empfangen oder gesendet werden kann (polling), ging alles glatt. Dabei dient das Zeichenecho, das vom accept
ausgegeben wird, als Schrittmacher für die weitere Übertragung, es fordert sozusagen selbst das nächste Zeichen an. So war es auch nicht mehr erforderlich im Terminal eine Zeitverzögerung nach jedem Zeichen einzustellen (character delay).
Dieses Warten auf ein Zeichenecho schließt auch das Steuerzeichen cr
(carriage return) mit ein. Und weil das Echo des cr
vom amforth erst dann erfolgt, wenn es den TIB
(terminal input buffer) komplett abgearbeitet hat, wartet das Terminal am Zeilendende auch brav solange, bis amforth wieder bereit ist neue Zeichen zu empfangen. So war es auch prima möglich neue Worte zu compilieren, was ja immer etwas länger dauert als die bloße Interpretation der empfangenen Worte. (Wir erinnern uns: Während der compilation - also schreiben ins flash - sind alle Interrupts aus. Und schaltet man sie danach wieder an, laufen rx0 und tx0 auch undefiniert, d.h. unsynchronisiert, los, was ebenfalls Fehler in der Übertragung macht.)
Wenn du also Ärger mit der Übertragung von Text an amforth hast, versuche dieses einfachere I/O.
; Simple USART I/O in amforth polling the UDR of USART. ; USART funktions: ; USART I/O Data Register UDR ; Write to UDR --> transmit character to terminal. ; Read from UDR <-- recieve character send by terminal. ; USART Control and Status Register A UCSRA ; Bit 7 RXC: USART Receive Complete ; Bit 6 TXC: USART Transmit Complete ; Bit 5 UDRE: USART Data Register Empty ; Bit 4 FE: Frame Error ; Bit 3 DOR: Data OverRun ; Bit 2 UPE: USART Parity Error ; Bit 1 U2X: Double the USART Transmission Speed ; Bit 0 MPCM: Multi-processor Communication Mode ; USART Control and Status Register B UCSRB ; Bit 7 RXCIE: RX Complete Interrupt Enable ; Bit 6 TXCIE: TX Complete Interrupt Enable ; Bit 5 UDRIE: USART Data Register Empty Interrupt Enable ; Bit 4 RXEN: Receiver Enable ; Bit 3 TXEN: Transmitter Enable ; Bit 2 UCSZ2: Character Size ; Bit 1 RXB8: Receive Data Bit 8 ; Bit 0 TXB8: Transmit Data Bit 8 ; USART Control and Status Register C UCSRC ; Bit 7 - nc ; Bit 6 UMSEL: USART Mode Select ; Bit 5:4 UPM1:0: Parity Mode ; Bit 3 USBS: Stop Bit Select ; Bit 2:1 UCSZ1:0: Character Size ; Bit 0 UCPOL: Clock Polarity ; USART Baud Rate Registers BRRL and UBRRH ; bit ruler ; %76543210 ; 11000 ; 110 ; ( -- v) System Value ; R( -- ) ; returns usart0 baudrate VE_BAUD0: .db 05,"baud0" .dw VE_HEAD .set VE_HEAD = VE_BAUD0 XT_BAUD0: .dw PFA_DOVALUE PFA_BAUD00: .dw 10 ; adjust settings to your needs. VE_USART0INIT: .db 10 ,"initusart0", 0 .dw VE_HEAD .set VE_HEAD = VE_USART0INIT XT_USART0INIT: .dw DO_COLON PFA_USART0INIT: ; ( -- ) .dw XT_DOLITERAL .dw $18 ; $18 . 11000 ok .dw XT_DOLITERAL .dw UCSRB .dw XT_CSTORE .dw XT_DOLITERAL .dw $6 ; $6 . 110 ok .dw XT_DOLITERAL .dw UCSRC .dw XT_CSTORE .dw XT_BAUD0 ; get sytem value from eeprom. .dw XT_DUP .dw XT_BYTESWAP .dw XT_DOLITERAL .dw UBRRH .dw XT_CSTORE .dw XT_DOLITERAL .dw UBRRL .dw XT_CSTORE .dw XT_EXIT ; Data register empty? UDRE=bit5 ) VE_DOEMITQ: .db 7 ,"doemit?" .dw VE_HEAD .set VE_HEAD = VE_DOEMITQ XT_DOEMITQ: .dw DO_COLON PFA_DOEMITQ: ; ( -- f ) .dw XT_DOLITERAL .dw UCSRA .dw XT_CFETCH .dw XT_DOLITERAL .dw $20 .dw XT_AND .dw XT_EXIT VE_DOEMIT: .db $6 ,"doemit",0 .dw VE_HEAD .set VE_HEAD = VE_DOEMIT XT_DOEMIT: .dw DO_COLON PFA_DOEMIT: ; ( c -- ) PFA_DOEMIT0: .dw XT_DOEMITQ .dw XT_DOCONDBRANCH .dw PFA_DOEMIT0 .dw XT_DOLITERAL .dw UDR .dw XT_CSTORE .dw XT_EXIT ; Recieve comlplete? RXC=bit7 ) VE_DOKEYQ: .db 6 ,"dokey?",0 .dw VE_HEAD .set VE_HEAD = VE_DOKEYQ XT_DOKEYQ: .dw DO_COLON PFA_DOKEYQ: ; ( -- f ) .dw XT_DOLITERAL .dw UCSRA .dw XT_CFETCH .dw XT_DOLITERAL .dw $80 .dw XT_AND .dw XT_EXIT VE_DOKEY: .db $5 ,"dokey" .dw VE_HEAD .set VE_HEAD = VE_DOKEY XT_DOKEY: .dw DO_COLON PFA_DOKEY: ; ( -- c ) PFA_DOKEY0: .dw XT_DOKEYQ ; begin .dw XT_DOCONDBRANCH .dw PFA_DOKEY0 ; until PFA_UDRFETCH: ; ( -- c ) .dw XT_DOLITERAL .dw UCSRA ; Must be read *bevor* udr, else not valid. .dw XT_CFETCH .dw XT_DOLITERAL .dw UDR .dw XT_CFETCH .dw XT_SWAP .dw XT_DOLITERAL .dw $8 .dw XT_AND ; Data overrun bit set? DOR=bit3 .dw XT_DOCONDBRANCH .dw PFA_UDRFETCH0 .dw XT_DOLITERAL .dw $80 .dw XT_OR ; Set bit7 in char to indicate DOR. PFA_UDRFETCH0: .dw XT_EXIT ; ' DOKEY is key ; ' DOEMIT is emit ; ' DOKEYQ is key? ; ' NOOP is /key ; ( -- ) Hardware Access ; R( --) ; set teriminal i/o vectors VE_SET_TERMINAL_VECTORS: .db 6, "set-tv", 0 .dw VE_HEAD .set VE_HEAD = VE_SET_TERMINAL_VECTORS XT_SET_TERMINAL_VECTORS: .dw DO_COLON PFA_SET_TERMINAL_VECTORS: ; ( -- ) .dw XT_DOLITERAL .dw XT_DOEMIT .dw XT_DOLITERAL .dw XT_EMIT .dw XT_DEFERSTORE .dw XT_DOLITERAL .dw XT_DOEMITQ .dw XT_DOLITERAL .dw XT_EMITQ .dw XT_DEFERSTORE .dw XT_DOLITERAL .dw XT_DOKEY .dw XT_DOLITERAL .dw XT_KEY .dw XT_DEFERSTORE .dw XT_DOLITERAL .dw XT_DOKEYQ .dw XT_DOLITERAL .dw XT_KEYQ .dw XT_DEFERSTORE .dw XT_DOLITERAL .dw XT_NOOP .dw XT_DOLITERAL .dw XT_SLASHKEY .dw XT_DEFERSTORE .dw XT_EXIT ; finis