1 ; con speed of TERMINAL link, there are three bottlenecks :
2 ; 1- time to send XOFF/RTS_high on CR (CR+LF=EOL), first emergency.
3 ; 2- the char loop time,
4 ; 3- the time between sending XON/RTS_low and clearing RX_TERM on first received char,
5 ; everything must be done to reduce these times, taking into account the necessity of switching to SLEEP (LPMx mode).
7 ; ----------------------------------;
8 ; (ACCEPT) part I: prepare TERMINAL_INT ;
9 ; ----------------------------------;
10 MOV #ENDACCEPT,S ;2 S = ACCEPT XOFF return
11 MOV #AKEYREAD1,T ;2 T = default XON return
12 PUSHM #3,IP ;5 PUSHM IP,S,T, as IP ret, XOFF ret, XON ret
13 MOV TOS,W ;1 -- addr len
14 MOV @PSP,TOS ;2 -- org ptr )
15 ADD TOS,W ;1 -- org ptr W=Bound )
16 MOV #0Dh,T ;2 T = 'CR' to speed up char loop in part II > prepare stack and registers
17 MOV #20h,S ;2 S = 'BL' to speed up char loop in part II ) for TERMINAL_INT use
18 BIT #RX_TERM,&TERM_IFG ;3 RX_Int ?
19 JZ ACCEPTNEXT ;2 no : case of quiet input terminal
20 MOV &TERM_RXBUF,Y ;3 yes: clear RX_Int
21 CMP #0Ah,Y ;2 received char = LF ? (end of downloading ?)
22 JNZ RXON ;2 no : RXON return = AKEYREAD1, to process first char of new line.
23 ACCEPTNEXT ADD #2,RSP ;1 yes: remove AKEYREAD1 as XON return,
24 PUSHM #3,S ;6 PUSHM S,T,W before SLEEP (and so WAKE on any interrupts)
26 ; ----------------------------------;
30 ; ----------------------------------;
31 RXON ; Software and/or hardware flow control, to start Terminal UART communication
32 ; ----------------------------------;
33 .IFDEF TERMINAL3WIRES ; first software flow control
34 RXON_LOOP BIT #TX_TERM,&TERM_IFG ;3 wait the sending of last char, useless at high baudrates
36 MOV #17,&TERM_TXBUF ;4 move char XON into TX_buf
38 .IFDEF TERMINAL4WIRES ; and hardware flow control after
39 BIC.B #RTS,&HANDSHAKOUT ;3 set RTS low
41 MOV @RSP+,PC ;4 to BACKGND (End of file download or quiet input) or AKEYREAD1...
42 ; ----------------------------------; ... (get next line of file downloading), or user defined
45 ; here we can add a preamble to BOR, executed by COLD, also by <RST> button
46 TERM_BUSY BIT #1,&TERM_STATW ;3
47 JNZ TERM_BUSY ;2 loop back while TERM_UART is busy
50 ; ----------------------------------;
51 RXOFF ; Software and/or hardware flow control, to stop Terminal UART comunication
52 ; ----------------------------------;
53 .IFDEF TERMINAL3WIRES ; first software flow control
54 RXOFF_LOOP BIT #TX_TERM,&TERM_IFG ;3 wait the sending of last char
56 MOV #19,&TERM_TXBUF ;4 move XOFF char into TX_buf
58 .IFDEF TERMINAL4WIRES ; and hardware flow control after
59 BIS.B #RTS,&HANDSHAKOUT ;3 set RTS high
61 MOV @RSP+,PC ;4 to ENDACCEPT, ...or user defined
62 ; ----------------------------------;
65 ; **********************************;
66 TERMINAL_INT ; <--- TEMR RX interrupt vector, delayed by the LPMx wake up time
67 ; **********************************; if wake up time increases, max bauds rate decreases...
68 ; (ACCEPT) part II under interrupt ; Org Ptr -- len'
69 ; ----------------------------------;
70 POPM #5,S ;8 POPM Y=SR,X=PC,W=buffer_bound, T=0Dh,S=20h
71 ; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv;
72 ; starts the 2th stopwatch ;
73 ; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;
74 AKEYREAD MOV.B &TERM_RXBUF,Y ;3 read character into Y, RX_TERM is cleared
75 ; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv;
76 ; stops the 3th stopwatch ; 3th bottleneck result : 17~ + LPMx wake_up time ( + 5~ XON loop if F/Bds<230401 )
77 ; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;
78 AKEYREAD1 ; <--- XON RET address 2 ; first emergency: anticipate XOFF on CR as soon as possible
79 CMP.B T,Y ;1 char = CR ?
80 JZ RXOFF ;2 then RET to ENDACCEPT
81 ; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv;+ 4 to send RXOFF
82 ; stops the first stopwatch ;= first bottleneck (empty line process), best case result: 20~ + LPMx wake_up time..
83 ; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; ...or 11~ in case of empty line
84 CMP.B S,Y ;1 printable char ?
86 CMP.B #8,Y ; char = BS ?
87 JNE WAITaKEY ; case of other control chars
88 ; ----------------------------------;
89 ; start of backspace ; made only by an human
90 ; ----------------------------------;
91 CMP @PSP,TOS ; Ptr = Org ?
92 JZ WAITaKEY ; yes: do nothing else
93 SUB #1,TOS ; no : dec Ptr
95 ; ----------------------------------;
97 ; ----------------------------------;
98 ASTORETEST CMP W,TOS ; 1 Bound is reached ?
99 JZ WAITaKEY ; 2 yes: loopback
100 MOV.B Y,0(TOS) ; 3 no: store char @ Ptr, send echo then loopback
101 ADD #1,TOS ; 1 increment Ptr
102 ; ----------------------------------;
103 WAITaKEY BIT #RX_TERM,&TERM_IFG ; 3 new char in TERMRXBUF ?
106 ; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv;
107 ; stops the 2th stopwatch ; best case result: 23~ ==> 434 kBds/MHz
108 ; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;
110 ; ----------------------------------;
111 ENDACCEPT ; --- Org Ptr r-- ACCEPT_ret
112 ; ----------------------------------;
113 CMP #0,&LINE ; if LINE <> 0...
115 ADD #1,&LINE ; ...increment LINE
116 ACCEPTEND SUB @PSP+,TOS ; -- len'
117 MOV @RSP+,IP ; 2 return to INTERPRET with GIE=0: FORTH is protected against any interrupt...
118 ; ----------------------------------;
119 MOV #LPM0+GIE,&LPM_MODE ; reset LPM_MODE to default mode LPM0 for next line of input stream
120 ; ----------------------------------;
121 MOV @IP+,PC ; ...until next falling down to LPMx mode of (ACCEPT) part1,
122 ; **********************************; i.e. when the FORTH interpreter has no more to do.
124 ; ------------------------------------------------------------------------------
125 ; TERMINAL I/O, input part
126 ; ------------------------------------------------------------------------------
129 ; https://forth-standard.org/standard/core/KEY
130 ; KEY -- c wait character from input device ; primary DEFERred word
131 KEY MOV @PC+,PC ;4 Code Field Address (CFA) of KEY
132 PFAKEY .word BODYKEY ; Parameter Field Address (PFA) of KEY, with default value
133 BODYKEY MOV &TERM_RXBUF,Y ;3 empty buffer
134 SUB #2,PSP ;1 push old TOS..
135 MOV TOS,0(PSP) ;3 ..onto stack
137 KEYLOOP BIT #RX_TERM,&TERM_IFG ; loop if bit0 = 0 in interupt flag register
139 MOV &TERM_RXBUF,TOS ;
143 ; ------------------------------------------------------------------------------
144 ; TERMINAL I/O, output part
145 ; ------------------------------------------------------------------------------
147 ;https://forth-standard.org/standard/core/EMIT
148 ;C EMIT c -- output character to the output device ; deferred word
149 FORTHWORD "EMIT" ; HalfDuplexEMIT
150 EMIT MOV @PC+,PC ;3 15~
151 PFAEMIT .word BODYEMIT ; Parameter Field Address (PFA) of EMIT, with its default value
152 BODYEMIT MOV TOS,Y ; 1
154 YEMIT1 BIT #TX_TERM,&TERM_IFG ; 3 wait the sending end of previous char, useless at high baudrates
156 .IFDEF TERMINAL5WIRES ;
157 YEMIT2 BIT.B #CTS,&HANDSHAKIN ;
160 YEMIT .word 4882h ; hi7/4~ lo:12/4~ send/send_not echo to terminal
161 .word TERM_TXBUF ; 3 MOV Y,&TERMTXBUF
165 ;Z ECHO -- connect terminal output (default)
166 ECHO MOV #4882h,&YEMIT ; 4882h = MOV Y,&<next_adr>
171 ;Z NOECHO -- disconnect terminal output
172 NOECHO MOV #NEXT,&YEMIT ; NEXT = 4030h = MOV @IP+,PC