; -*- coding: utf-8 -*-
-
+;
; ---------------------------------------
-; TERMINAL driver for FastForth target
+; UART TERMINAL driver for FastForth target
; ---------------------------------------
-; +---------------------------+
-; ------ | +-----------------+ |
-; WIRING | | +--------+ | |
-; ------ | | | | | |
-; FastForth target TXD RXD RTS <--> CTS TXD RXD UARTtoUSB <--> COMx <--> TERMINAL
-; -----------------------------------------------------------------------------------------
-; MSP_EXP430FR5739 P2.0 P2.1 P2.2 PL2303TA TERATERM.EXE
-; MSP_EXP430FR5969 P2.0 P2.1 P4.1 PL2303HXD
-; MSP_EXP430FR5994 P2.0 P2.1 P4.2 CP2102
-; MSP_EXP430FR6989 P3.4 P3.5 P3.0
-; MSP_EXP430FR4133 P1.0 P1.1 P2.3
-; CHIPSTICK_FR2433 P1.4 P1.5 P3.2
-; MSP_EXP430FR2433 P1.4 P1.5 P1.0
+;
+; +---------------------------------------+
+; | +-----------------------------+ |
+; | | +------(option)-----+ | |
+; | | | | | |
+; FastForth target: TXD RXD RTS connected to : CTS TXD RXD of UARTtoUSB <--> COMx <--> TERMINAL
+; ---------------- --- --- --- --- --- --- -------------------------------------
+; MSP_EXP430FR5739 P2.0 P2.1 P2.2 PL2303TA TERATERM.EXE
+; MSP_EXP430FR5969 P2.0 P2.1 P4.1 PL2303HXD
+; MSP_EXP430FR5994 P2.0 P2.1 P4.2 CP2102
+; MSP_EXP430FR6989 P3.4 P3.5 P3.0
+; MSP_EXP430FR4133 P1.0 P1.1 P2.3
+; CHIPSTICK_FR2433 P1.4 P1.5 P3.2
+; MSP_EXP430FR2433 P1.4 P1.5 P1.0
; MSP_EXP430FR2355 P4.3 P4.2 P2.0
; LP_MSP430FR2476 P1.4 P1.5 P6.1
-
-
+;
;-------------------------------------------------------------------------------
-; UART TERMINAL: QABORT ABORT_TERM COLD_TERM INI_TERM RXON RXOFF
+; UART TERMINAL: QABORT COLD_TERM INIT_TERM RXON RXOFF
;-------------------------------------------------------------------------------
-; define run-time part of ABORT"
-;Z ?ABORT xi f c-addr u -- abort & print msg.
-; FORTHWORD "?ABORT"
+
+; define run-time part of ABORT" ; if f is true display msg. then abort current process
QABORT CMP #0,2(PSP) ; -- f c-addr u test flag f
- JNZ ABORT_TERM ;
+ JNZ ABORT_TERM ; see forthMSP430FR_TERM_xxxx.asm below
THREEDROP ADD #4,PSP ; -- u
- MOV @PSP+,TOS ; --
- MOV @IP+,PC ;
+ JMP DROP ;
; ----------------------------------;
-ABORT_TERM ; exit from downloading file then reinit some variables via INI_FORTH
+UART_ABORT_TERM ; exit from downloading then reinit some variables via INIT_FORTH
; ----------------------------------;
- CALL #RXON ; PFA resume downloading source file if any
+ABORT_TERM CALL #RXON ; resume downloading source file if any
A_UART_LOOP BIC #RX_TERM,&TERM_IFG ; clear RX_TERM
MOV &FREQ_KHZ,Y ; 1000, 2000, 4000, 8000, 16000, 240000
A_USB_LOOPJ MOV #65,X ; 2~ <-------+ linux with minicom seems very very slow...
JNZ A_USB_LOOPJ ; 2~ 200~ loop -----+
BIT #RX_TERM,&TERM_IFG ; 4 new char in TERMRXBUF after A_USB_LOOPJ delay ?
JNZ A_UART_LOOP ; 2 yes, the input stream is still active: loop back
- CALL #INI_FORTH ; common ?ABORT|RST subroutine
-; ----------------------------------;
- .word lit,LINE,FETCH ; -- f c-addr u line fetch line number before set ECHO !
- .word ECHO ;
+ CALL #INIT_FORTH ; common ?ABORT|PUC subroutine to init DEFERed definitions
+ ; cnt is a byte, always positive. If cnt = 0 no RST_RET.
+ .word DUP ;
+ .word QFBRAN,ABORT_END; display nothing, don't force ECHO if ABORT" empty string
+ .word ECHO ; force ECHO
.word XSQUOTE ;
- .byte 4,27,"[7m" ; type ESC[7m (set reverse video)
- .word TYPE ;
-; ----------------------------------;
- .word QDUP,QFBRAN ; do nothing if line = 0
- .word ABORT_TYPE ;
+ .byte 4,27,"[7m" ;
+ .word TYPE ; type ESC [7m (set reverse video)
; ----------------------------------;
-; Display error "line:xxx" ; -- f c-addr u line
+; Display QABORT|WARM message ; <== WARM jumps here
; ----------------------------------;
- .word XSQUOTE ; -- f c-addr u line c-addr1 u1 displays the line where error occured
- .byte 15,"LAST.4TH, line " ;
- .word TYPE ; -- f c-addr u line
- .word UDOT ; -- f c-addr u
-; ----------------------------------;
-; Display ABORT message ; <== WARM jumps here
-; ----------------------------------;
-ABORT_TYPE .word TYPE ; -- f type abort message
+ABORT_TYPE .word TYPE ; -- f type QABORT|WARM message
.word XSQUOTE ; -- f c-addr u
.byte 4,27,"[0m" ;
- .word TYPE ; -- f set normal video
- .word ABORT ; no return
-
-
-; ----------------------------------;
-COLD_TERM ; default STOP_APP: wait TERMINAL idle
-; ----------------------------------;
-UART_COLD_TERM
- BIT #1,&TERM_STATW ;3
- JNZ COLD_TERM ;2 loop back while TERM_UART is busy
- MOV @RSP+,PC ; return to software_BOR
+ .word TYPE ; -- f set normal video
+ABORT_END .word ABORT ; -- f no return
; ----------------------------------;
+;-------------------------------------------------------------------------------
+; INIT TERMinal then enable I/O ;
+;-------------------------------------------------------------------------------
+UART_INIT_TERM ; see MSP430FRxxxx.pat file
; ----------------------------------;
-INIT_TERM ; TOS = RSTIV_MEM
-; ----------------------------------;
-UART_INIT_TERM ;
- CMP #2,TOS ;
- JNC UART_INIT_TERM_END ; no INIT_TERM if RSTIV_MEM U< 2 (WARM)
-; ----------------------------------;
+INIT_TERM ; TOS = USERSYS, don't change it
+ CALL #COLD_TERM ; wait while TERM_UART is busy
MOV #0081h,&TERM_CTLW0 ; UC SWRST + UCLK = SMCLK
MOV &TERMBRW_RST,&TERM_BRW ; init value in FRAM
MOV &TERMMCTLW_RST,&TERM_MCTLW ; init value in FRAM
BIC #1,&TERM_CTLW0 ; release UC_TERM from reset...
BIS #WAKE_UP,&TERM_IE ; then enable interrupt for wake up on terminal input
BIC #LOCKLPM5,&PM5CTL0 ; activate all previous I/O settings.
-UART_INIT_TERM_END
MOV @RSP+,PC ; RET
; ----------------------------------;
-
-; ----------------------------------;
-RXON ; default BACKGND_APP
-; ----------------------------------;
-UART_RXON JMP RXON_EXE ; Software and/or hardware flow control, to start Terminal UART for one line
-; ----------------------------------;
-
; ----------------------------------;
-RXOFF ; Software and/or hardware flow control, to stop Terminal UART comunication
+UART_COLD_TERM ; default STOP_APP: wait TERMINAL idle
; ----------------------------------;
-UART_RXOFF ;
- .IFDEF TERMINAL3WIRES ; first software flow control
-RXOFF_LOOP BIT #TX_TERM,&TERM_IFG ;3 wait the sending of last char
- JZ RXOFF_LOOP ;2
- MOV #19,&TERM_TXBUF ;4 move XOFF char into TX_buf
- .ENDIF ;
- .IFDEF TERMINAL4WIRES ; and hardware flow control after
- BIS.B #RTS,&HANDSHAKOUT ;3 set RTS high
- .ENDIF ;
- MOV @RSP+,PC ;4 to CR_NEXT, ...or user defined
+WAIT_UART_IDLE
+COLD_TERM BIT #1,&TERM_STATW ;3 uart busy ?
+ JNZ COLD_TERM ;2 loop back while TERM_UART is busy
; ----------------------------------;
-
+UART_INIT_SOFT ;
; ----------------------------------;
-RXON_EXE
+INIT_SOFT_TERM
+ MOV @RSP+,PC ; does nothing by default
; ----------------------------------;
- .IFDEF TERMINAL3WIRES ; first software flow control
-RXON_LOOP BIT #TX_TERM,&TERM_IFG ;3 wait the sending of last char, useless at high baudrates
- JZ RXON_LOOP ;2
- MOV #17,&TERM_TXBUF ;4 move char XON into TX_buf
- .ENDIF ;
- .IFDEF TERMINAL4WIRES ; and hardware flow control after
- BIC.B #RTS,&HANDSHAKOUT ;3 set RTS low
- .ENDIF ;
- MOV @RSP+,PC ;4 to BACKGND (End of file download or quiet input) or AKEYREAD...
-; ----------------------------------; ... (get next line of file downloading), or user defined
-
-;===============================================================================
- FORTHWORD "WIPE" ; software DEEP_RESET
-;===============================================================================
-WIPE MOV #-1,&RSTIV_MEM ; negative value ==> DEEP_RESET
- JMP COLD
-
-;===============================================================================
- FORTHWORD "COLD"
-;===============================================================================
-;Z COLD -- performs a software RESET
-; as pin RST is replaced by pin NMI, RESET by pin activation is redirected here via USER NMI vector
-; that allows actions to be performed before executing software BOR.
-COLD CALL @PC+ ; COLD first calls STOP_APP, in this instance: CALL #COLD_TERM by default
-PFACOLD .word COLD_TERM ; INI_COLD_DEF: default value set by WIPE. see forthMSP430FR_TERM_xxxx.asm
- BIT.B #IO_WIPE,&WIPE_IN ; hardware Deep_RESET request (low) ?
- JNZ COLDEXE ; no
- MOV #-1,&RSTIV_MEM ; yes, set negative value to force DEEP_RESET
-COLDEXE MOV #0A504h,&PMMCTL0 ; performs software_BOR, see RESET in forthMSP430FR.asm
-; ----------------------------------;
-
-;-----------------------------------;
- FORTHWORD "WARM" ;
-;-----------------------------------;
-;Z WARM xi -- ; the end of RESET
-;-----------------------------------;
-WARM ;
;-------------------------------------------------------------------------------
-; RESET 7: if RSTIV_MEM <> WARM, init TERM and enable I/O
+; UART TERMINAL : WARM SYS COLD
;-------------------------------------------------------------------------------
- CALL @PC+ ; init TERM, only if TOS U>= 2 (RSTIV_MEM <> WARM)
- .IFNDEF SD_CARD_LOADER ;
-PFAWARM .word INIT_TERM ; INI_HARD_APP default value, init TERM UC, unlock I/O's, TOS = RSTIV_MEM
- .ELSE
-PFAWARM .word INI_HARD_SD ; init SD Card + init TERM, see forthMSP430FR_SD_INIT.asm
- .ENDIF ; TOS = RSTIV_MEM
-;-----------------------------------;
-WARM_DISPLAY ; TOS = RSTIV_MEM value
- ASMtoFORTH
+; ----------------------------------; thanks to INIT_FORTH, WARM implements the choice
+UART_WARM ; made by the user with SYS|hardwareRST|DEEP_reset
+;-----------------------------------; regarding the state of the software.
+WARM CALL &HARD_APP ;
+ mASM2FORTH ;
+ .word ECHO ;
.word XSQUOTE
.byte 7,13,10,27,"[7m#" ; CR + cmd "reverse video" + #
.word TYPE
- .word DOT ; display TOS = RSTIV_MEM value
+ .word DOT ; display TOS = USERSYS value
.word XSQUOTE
- .byte 25,"FastForth ©J.M.Thoorens "
+ .byte 25,"FastForth ",169,"J.M.Thoorens, "
.word TYPE
- .word LIT,FRAM_FULL,HERE,MINUS,UDOT
+ .word LIT,FRAM_FULL
+ .word HEREXEC,MINUS,UDOT
.word XSQUOTE
.byte 10,"bytes free"
- .word BRAN,ABORT_TYPE ; without return
+ .word BRAN,ABORT_TYPE ; without return!
+;-----------------------------------;
+
+;-----------------------------------;
+ FORTHWORD "SYS" ; n -- software RST, DEEP_RST, COLD, WARM
+;-----------------------------------;
+ CMP #0,TOS ;
+ JL SYSEND ; if -n SYS ==> COLD + DEEP_RESET
+ JZ NOPUC ; if [0] SYS
+ BIT #1,TOS ;
+ JNC SYSEND ; if +n SYS (+n even)
+NOPUC PUSH #WARM ;
+ PUSH RSP ; Push address of WARM address
+ JMP INIT_FORTH ; if +n SYS (+n odd) ==> INIT_FORTH --> WARM --> WARM display
+SYSEND MOV TOS,&USERSYS ; ==> COLD --> PUC --> INIT_FORTH --> WARM --> WARM display
+;===============================================================================
+COLD ; <--- USER_NMI vector <--- <RESET> and <RESET> + <SW1> (DEEP_RESET)
+;===============================================================================
+; as pin RST is replaced by pin NMI, RESET by pin activation is redirected here via USER NMI vector
+; that allows actions to be performed before executing software BOR.
+ CALL &COLD_APP ; to stop APPlication before reset
+ BIT.B #SW1,&SW1_IN ; <SW1> pressed ?
+ JNZ COLDEXE ; no
+ MOV #-1,&USERSYS ; yes, set negative value to force DEEP_RESET
+COLDEXE MOV #0A504h,&PMMCTL0 ; performs software_BOR ------------------------+
+;=============================================================================== |
+RESET ; <-- RST vect. <-- SYS_failures PUC POR BOR <--+
+;===============================================================================
+; PUC 1: replace pin RESET by pin NMI, stops WDT_RESET
+;-------------------------------------------------------------------------------
+ BIS #3,&SFRRPCR ; pin RST becomes pin NMI with falling edge, so SYSRSTIV = 4
+ BIS #10h,&SFRIE1 ; enable NMI interrupt ==> hardware RESET is redirected to COLD.
+ MOV #5A80h,&WDTCTL ; disable WDT RESET
+;-------------------------------------------------------------------------------
+; PUC 2: INIT STACK
+;-------------------------------------------------------------------------------
+ MOV #RSTACK,RSP ; init return stack
+ MOV #PSTACK,PSP ; init parameter stack
+;-------------------------------------------------------------------------------
+; PUC 3: I/O, RAM, RTC, CS, SYS initialisation limited to FastForth usage.
+; All unused I/O are set as input with pullup resistor.
+;-------------------------------------------------------------------------------
+ .include "TargetInit.asm" ; include target specific init code
+;-------------------------------------------------------------------------------
+; PUC 4: init RAM to 0
+;-------------------------------------------------------------------------------
+ MOV #RAM_LEN,X ; 2 RAM_LEN must be even and > 1, obviously.
+INITRAMLOOP SUB #2,X ; 1
+ MOV #0,RAM_ORG(X) ; 3
+ JNZ INITRAMLOOP ; 2 6 cycles loop !
+;-------------------------------------------------------------------------------
+; PUC 5: GET SYSRSTIV and SYS_USER ; X = 0
+;-------------------------------------------------------------------------------
+ MOV &SYSRSTIV,X ; X <-- SYSRSTIV <-- 0
+ MOV &USERSYS,TOS ; TOS = USERSYS
+ MOV #0,&USERSYS ; clear USERSYS
+ AND #-1,TOS ;
+ JNZ PUC6 ; if TOS <> 0, keep USERSYS value
+ MOV X,TOS ; TOS <-- SYSRSTIV
+;-------------------------------------------------------------------------------
+; PUC 6: START FORTH engine
+;-------------------------------------------------------------------------------
+PUC6 CALL #INIT_FORTH ; common part of QABORT|PUC
+PUCNEXT .WORD WARM ; no return. May be redirected by BOOT.
+;-----------------------------------;
;-------------------------------------------------------------------------------
-; INTERPRETER INPUT
+; INTERPRETER INPUT: ACCEPT KEY EMIT ECHO NOECHO
;-------------------------------------------------------------------------------
FORTHWORD "ACCEPT"
+;-----------------------------------;
;https://forth-standard.org/standard/core/ACCEPT
;C ACCEPT addr addr len -- addr len' get line at addr to interpret len' chars
ACCEPT MOV @PC+,PC ;3 Code Field Address (CFA) of ACCEPT
PFAACCEPT .word BODYACCEPT ; Parameter Field Address (PFA) of ACCEPT
-BODYACCEPT ; BODY of ACCEPT = default execution of ACCEPT
; ----------------------------------;
; ACCEPT part I prepare TERMINAL_INT;
; ----------------------------------;
- MOV TOS,X ;1 -- addr len
+BODYACCEPT MOV TOS,X ;1 -- addr len
MOV @PSP,TOS ;2 -- org ptr
ADD TOS,X ;1 -- org ptr X = buf_end
MOV #0Dh,W ;2 W = 'CR' to speed up char loop in part II
MOV #20h,T ;2 T = 'BL' to speed up char loop in part II
MOV IP,S ; S = ACCEPT_ret
- MOV #CR_NEXT,IP ;2 IP = XOFF_ret
+ MOV #CR_NEXT,IP ;2 IP = XOFF_ret
PUSHM #5,IP ;5 PUSHM IP,S,T,W,X r-- XOFF_ret ACCEPT_ret BL CR buf_end
- JMP SLEEP ;2 which calls RXON before falling down to LPMx mode
+ JMP SLEEP ;2
; ----------------------------------;
; **********************************;
; (ACCEPT) part II under interrupt ; Org Ptr -- len'
; ----------------------------------;
ADD #4,RSP ;1 remove SR and PC from stack, SR flags are lost (unused by FORTH interpreter)
- POPM #4,IP ;6 POPM W=buffer_bound, T=0Dh, S=20h, IP=ACCEPT_RET r-- XOFF_ret
-; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv;
-; starts the 2th stopwatch ;
-; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;
+ POPM #3,IP ;6 POPM W=buffer_bound, T=0Dh, S=20h, IP=ACCEPT_RET r-- XOFF_ret
+; ----------------------------------;
AKEYREAD MOV.B &TERM_RXBUF,Y ;3 read character into Y, RX_TERM is cleared
; ----------------------------------;
CMP.B T,Y ;1 CR ?
- JZ RXOFF ;2 then RET to CR_NEXT
-; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv;+ 12 to send RXOFF
-; stops the first stopwatch ;= first bottleneck, best case result: 25~ + LPMx wake_up time..
-; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;
- CMP.B S,Y ;1 printable char ?
+ JNZ AKEYRDNNEXT ;2 no
+; ----------------------------------;
+RXOFF ; Software|hardware flow control to stop RX UART r-- ACCEPT_ret CR_NEXT
+; ----------------------------------;
+ .IFDEF TERMINAL3WIRES ; first software flow control
+RXOFF_LOOP BIT #TX_TERM,&TERM_IFG ;3 wait the sending of last char
+ JZ RXOFF_LOOP ;2
+ MOV #19,&TERM_TXBUF ;4 move XOFF char into TX_buf
+ .ENDIF ;
+ .IFDEF TERMINAL4WIRES ; and hardware flow control after
+ BIS.B #RTS,&HANDSHAKOUT ;3 set RTS high
+ .ENDIF ;
+ MOV @RSP+,PC ;4 to CR_NEXT
+; ----------------------------------;
+AKEYRDNNEXT CMP.B S,Y ;1 printable char ?
JC ASTORETEST ;2 yes
; ----------------------------------;
CMP.B #8,Y ;1 char = BS ?
; end of backspace ;
; ----------------------------------;
ASTORETEST CMP W,TOS ; 1 Bound is reached ?
- JZ YEMIT ; 2 yes: send echo then loopback
- MOV.B Y,0(TOS) ; 3 no: store char @ Ptr, send echo then loopback
+ JC YEMIT ; 2 yes: don't store char @ Ptr, don't increment TOS
+ MOV.B Y,0(TOS) ; 3 no: store char @ Ptr
ADD #1,TOS ; 1 increment Ptr
; ----------------------------------;
WAITaKEY BIT #RX_TERM,&TERM_IFG ; 3 new char in TERMRXBUF ?
JNZ AKEYREAD ; 2 yes
-; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv;
-; stops the 2th stopwatch ; best case result: 26~/22~ (with/without echo) ==> 385/455 kBds/MHz
-; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;
JZ WAITaKEY ; 2 no
; ----------------------------------;
-
-; ----------------------------------;
; return of RXOFF
; ----------------------------------;
CR_NEXT SUB @PSP+,TOS ; -- len'
-; ----------------------------------;
- MOV #LPM0+GIE,&LPM_MODE ; reset LPM_MODE to default mode LPM0 for next line of input stream
-; ----------------------------------;
WAITLF BIT #RX_TERM,&TERM_IFG ; char 'LF' is received ?
JZ WAITLF ; no
MOV.B &TERM_RXBUF,Y ; yes, clear RX_int flag after LF received
; ----------------------------------;
-ACCEPT_EOL CMP #0,&LINE ; if LINE <> 0 increment LINE
- JZ ACCEPT_END ;
- ADD #1,&LINE ;
-ACCEPT_END
-; ----------------------------------;
- MOV S,Y ; output a BL on TERMINAL (for the case of error occuring)
- JMP YEMIT ; before interpret line
-; **********************************;
+ACCEPT_EOL MOV S,Y ; output a BL on TERMINAL (for the case of error occuring)
+ JMP YEMIT ; before return to ABORT to interpret line
+; **********************************; UF9 to UF11 are reset.
; ------------------------------------------------------------------------------
; TERMINAL I/O, input part
; KEY -- c wait character from input device ; primary DEFERred word
KEY MOV @PC+,PC ;4 Code Field Address (CFA) of KEY
PFAKEY .word BODYKEY ; Parameter Field Address (PFA) of KEY, with default value
-BODYKEY SUB #2,PSP ;1 push old TOS..
+BODYKEY PUSH #KEYNEXT ;
+; ----------------------------------;
+RXON ; default BACKGND_APP
+; ----------------------------------;
+ .IFDEF TERMINAL3WIRES ; first software flow control
+RXON_LOOP BIT #TX_TERM,&TERM_IFG ;3 wait the sending of last char, useless at high baudrates
+ JZ RXON_LOOP ;2
+ MOV #17,&TERM_TXBUF ;4 move char XON into TX_buf
+ .ENDIF ;
+ .IFDEF TERMINAL4WIRES ; and hardware flow control after
+ BIC.B #RTS,&HANDSHAKOUT ;3 set RTS low
+ .ENDIF ;
+ MOV @RSP+,PC ;4 to BACKGND (End of file download or quiet input) or AKEYREAD...
+; ----------------------------------; ... (get next line of file downloading), or user defined
+KEYNEXT SUB #2,PSP ;1 push old TOS..
MOV TOS,0(PSP) ;3 ..onto stack
- CALL #RXON
KEYLOOP BIT #RX_TERM,&TERM_IFG ; loop if bit0 = 0 in interupt flag register
JZ KEYLOOP ;
MOV &TERM_RXBUF,TOS ;
YEMIT1 BIT.B #CTS,&HANDSHAKIN ;
JNZ YEMIT1
.ENDIF
-QYEMIT .word 48C2h ;3 48C2h = MOV.B Y,&<next_adr>
- .word TERM_TXBUF ; 3 MOV Y,&TERMTXBUF
+QYEMIT MOV.B Y,&TERM_TXBUF ; 3 may be replaced by MOV @IP+,PC with NOECHO
MOV @IP+,PC ;
FORTHWORD "ECHO"
;Z ECHO -- connect terminal output (default)
ECHO MOV #48C2h,&QYEMIT ; 48C2h = MOV.B Y,&<next_adr>
- MOV #0,&LINE ;
MOV @IP+,PC
FORTHWORD "NOECHO"
;Z NOECHO -- disconnect terminal output
NOECHO MOV #NEXT,&QYEMIT ; NEXT = 4030h = MOV @IP+,PC
- MOV #1,&LINE ;
MOV @IP+,PC
+