;; Хронограф с выводом результата на LCD дисплей (8х2 в одну строку) и COM порт.
;; Распиновка микросхемы
;; PIN I/O FROM TO
;;----------------------------------------------------------------------
;; A0 O E LCD E
;; A1 O RS LCD RS
;; A2 I BIT 2 SENSOR_1
;; A3 I BIT 3 SENSOR_2
;; A4 O
;; A5 O
;; A6 O
;; A7 O
;;
;; B0 0
;; B1 I RS232 RX PC RX
;; B2 O RS232 TX PC TX
;; B3 O
;; B4 O BIT 4 LCD BIT 4
;; B5 O BIT 5 LCD BIT 5
;; B6 O BIT 6 LCD BIT 6
;; B7 O BIT 7 LCD BIT 7
;;----------------------------------------------------------------------

list p=16F628A
#include <P16F628A.INC>

#DEFINE BANK0 BCF STATUS, RP0
#DEFINE BANK1 BSF STATUS, RP0
;~~~~~~~~~~~~~MACROS~~~~~~~~~~~~~~~
LOADF MACRO F_VAR, LIT_NUM
MOVLW LIT_NUM
MOVWF F_VAR
ENDM
MOVF_F MACRO F_FROM, F_TO
MOVF F_FROM, W
MOVWF F_TO
ENDM
CHR_LCD_OUT MACRO LIT_NUM
MOVLW LIT_NUM
MOVWF CHAR
CALL SEND_CHAR
ENDM
MEM_LCD_OUT MACRO LIT_NUM
MOVF LIT_NUM, W
MOVWF CHAR
CALL SEND_CHAR
ENDM
;~


__CONFIG _LVP_OFF & _MCLRE_OFF & _XT_OSC & _BODEN_OFF & _CP_OFF & _WDT_OFF & _PWRTE_ON
ERRORLEVEL -302

#DEFINE E PORTA, 0 ;; OUTPUT TO LCD
#DEFINE RS PORTA, 1 ;; OUTPUT TO LCD
#DEFINE SENSOR_1 PORTA, 2 ;; INPUT
#DEFINE SENSOR_2 PORTA, 3 ;; INPUT

CBLOCK 0X20
CNTJ ;; FOR MS_DELAY
; BIT8, CNT1, CNT2, TEMP_MUL, HI16, LO16 ;; FOR MUL_BY_1000
MS_TIME, MS_TIME_TEMP
LO_BYTE, HI_BYTE ;; FOR LCD DRIVER
CHAR ;; FOR DATA CONVERTION
TEN_K, THOU, HUND, TENS, ONES
DIVIDEND1, DIVIDEND2, DIVIDEND3, DIVISOR1, DIVISOR2
DVDEND_HI, DVDEND_LO
TIME_HI, TIME_LO, NUMH, NUML
IF_ERROR ;; Признак ошибки
ENDC

ACC EQU 0x5C ; Most significant Byte
SIGN EQU 0x62 ; save location for sign in MSB
TEMP EQU 0x68 ; temporary storage
DIVIDEND EQU 0x5C ; Most significant Byte
DIVISOR EQU 0x65 ; Most significant Byte
REMAIN EQU 0x60 ; Most significant Byte
LOOPCOUNT EQU 0x63 ; loop counter

ORG 0x000
CALL init_pic
GOTO MAIN

ORG 0x004
GOTO int_t

init_pic
;----------------------------PORT I/O CONFIGURATION/SETUP-------------------------------
BANK0
MOVLW 0X07
MOVWF CMCON ;; DISABLE CAPTURE/COMPARE MODULES.

BANK1
LOADF TRISA, B'00101100'
LOADF TRISB, B'00000110' ;; SET BITS 1, 2 FOR USART.
BSF OPTION_REG, NOT_RBPU ;; BCF/BSF = ENABLE/DISABLE PULL-UP.

;------------------POWER ON RESET CONFIGURATION/SETUP--------------------------
BSF PCON, OSCF ;BCF/BSF = 37KHZ/4MHZ INTRC OR ER OSCILLATOR SPEED.

;--------------------------INTERRUPT CONFIGURATION/SETUP-------------------------------
; BANK1
; BCF INTCON, GIE ;BCF/BSF = DIS/ENABLE GLOBAL INTERRUPT.
; BCF INTCON, PEIE ;BCF/BSF = DIS/ENABLE Разрешение прерываний от переферийных модулей
; BCF INTCON, T0IE ;BCF/BSF = DIS/ENABLE Разрешение прерывания по переполнению TMR0
; BCF INTCON, INTE ;BCF/BSF = DIS/ENABLE RB0 INTERRUPT.
; BCF INTCON, RBIE ;BCF/BSF = DIS/ENABLE RB7-4 INTERRUPT.
BSF PIE1, TMR1IE ;BCF/BSF = DIS/ENABLE Разрешение прерывания по переполнению TMR1
;--------------------------------------------------------------------------------------

;-------------------------USART CONFIGURATION/SETUP------------------------------------
BANK1
BCF PIE1, TXIE ;BCF/BSF = DIS/ENABLE TX INTERRUPT.
BSF TXSTA, CSRC ;BCF/BSF = EXT/INTERNAL GENERATOR.
BCF TXSTA, TX9 ;BCF/BSF = 8-BIT/9-BIT TRANSMISSION.
BSF TXSTA, TXEN ;BCF/BSF = DIS/ENABLE TRANSMISSION.
BCF TXSTA, SYNC ;BCF/BSF = A/SYNCHRONOUS MODE.
BSF TXSTA, BRGH ;BCF/BSF = LO/HI SPEED BAUD RATE SELECT.
LOADF SPBRG, .12 ;SET BAUD RATE TO 19.2 KBPS.
BANK0
BSF RCSTA, SPEN ;BCF/BSF = DIS/ENABLE SERIAL PORT.
BCF RCSTA, RX9 ;BCF/BSF = 8-BIT/9-BIT TRANSMISSION.
BSF RCSTA, SREN ;BCF/BSF = DIS/ENABLE SINGLE RECEIVE.
BCF RCSTA, CREN ;BCF/BSF = DIS/ENABLE CONTINUOS RECEIVE.
BSF RCSTA, SPEN ;BCF/BSF = DIS/ENABLE SERIAL PORT.
;--------------------------------------------------------------------------------------
RETURN

;*********************MAIN***********************
MAIN:
CALL INIT_LCD

ERR_TEST:
CALL CLEAR
CALL GET_ERROR
BTFSC IF_ERROR, 7
GOTO ERR_TEST
CALL CLEAR
CALL LCD_1

GET:
CALL GET_VELOCITY
CALL SEND_USART
CALL LCD_UPDATE
GOTO GET

;*****************END 0F MAIN******************

int_t
BCF T1CON, TMR1ON ;BCF/BSF = DISABLE/ENABLE TIMER1 ON.
BCF PIE1, TMR1IF ;BCF/BSF = DISABLE/ENABLE Разрешение прерывания по переполнению TMR1

CLRF TMR1L ;; THEN, START TIMING.
CLRF TMR1H

MOVF_F TMR1L, TIME_LO ;; FINALY, COPY TIMER1 INTO LO/HI BYTES.
MOVF_F TMR1H, TIME_HI

GOTO ERR_TEST

;Проверяем датчики
GET_ERROR: ;; DUAL SENSOR DETECTION.
BCF IF_ERROR, 7

LOADF CHAR, 0X00
CALL SET_ADDRESS

BTFSS SENSOR_1
GOTO $ + 3
CALL D1_ER
GOTO $ + 2
CALL D1_OK

LOADF CHAR, 0X40
CALL SET_ADDRESS

BTFSS SENSOR_2
GOTO $ + 3
CALL D2_ER
GOTO $ + 2
CALL D2_OK


LOADF MS_TIME, .250 ;; 1.5 SEC DELAY.
CALL MS_DELAY
CALL MS_DELAY
CALL MS_DELAY
CALL MS_DELAY
CALL MS_DELAY
CALL MS_DELAY
RETURN

D1_OK:
CHR_LCD_OUT 'D'
CHR_LCD_OUT '1'
CHR_LCD_OUT '-'
CHR_LCD_OUT 'O'
CHR_LCD_OUT 'K'
CHR_LCD_OUT ' '
CHR_LCD_OUT ' '
CHR_LCD_OUT ' '
RETURN

D1_ER:
CHR_LCD_OUT 'D'
CHR_LCD_OUT '1'
CHR_LCD_OUT '-'
CHR_LCD_OUT 'E'
CHR_LCD_OUT 'R'
CHR_LCD_OUT ' '
CHR_LCD_OUT ' '
CHR_LCD_OUT ' '
BSF IF_ERROR, 7
RETURN

D2_OK:
CHR_LCD_OUT 'D'
CHR_LCD_OUT '2'
CHR_LCD_OUT '-'
CHR_LCD_OUT 'O'
CHR_LCD_OUT 'K'
CHR_LCD_OUT ' '
CHR_LCD_OUT ' '
CHR_LCD_OUT ' '
RETURN

D2_ER:
CHR_LCD_OUT 'D'
CHR_LCD_OUT '2'
CHR_LCD_OUT '-'
CHR_LCD_OUT 'E'
CHR_LCD_OUT 'R'
CHR_LCD_OUT ' '
CHR_LCD_OUT ' '
CHR_LCD_OUT ' '
BSF IF_ERROR, 7
RETURN
;---------------------------------------

;Первоначальная надпись на LCD
LCD_1:
LOADF CHAR, 0X00
CALL SET_ADDRESS

CHR_LCD_OUT 'A'
CHR_LCD_OUT 'W'
CHR_LCD_OUT 'A'
CHR_LCD_OUT 'I'
CHR_LCD_OUT 'T'
CHR_LCD_OUT ' '
CHR_LCD_OUT '-'
CHR_LCD_OUT ' '

LOADF CHAR, 0X40
CALL SET_ADDRESS

CHR_LCD_OUT 'S'
CHR_LCD_OUT 'H'
CHR_LCD_OUT 'O'
CHR_LCD_OUT 'O'
CHR_LCD_OUT 'T'
CHR_LCD_OUT '!'
CHR_LCD_OUT '!'
CHR_LCD_OUT '!'
RETURN
;---------------------------------------

;DETECTION AND TIMING OF PROJECTILE
GET_VELOCITY: ;; DUAL SENSOR DETECTION.DUAL SENSOR DETECTION.
CLRF TMR1L ;; THEN, START TIMING.
CLRF TMR1H

BSF INTCON, GIE ;BCF/BSF = DISABLE/ENABLE Глобальное разрешение прерываний
BSF INTCON, PEIE ;BCF/BSF = DIS/ENABLE Разрешение прерываний от переферийных модулей

BTFSS SENSOR_1 ;; AWAIT DETECTION: ACTIVE HI.
GOTO $ - 1

BSF T1CON, TMR1ON ;BCF/BSF = DISABLE/ENABLE TIMER1 ON.

BTFSS SENSOR_2 ;; NEXT, AWAIT DETECTION: ACTIVE HI.
GOTO $ - 1

BCF T1CON, TMR1ON ;BCF/BSF = DISABLE/ENABLE TIMER1 ON.

BCF INTCON, GIE ;BCF/BSF = DISABLE/ENABLE Глобальное разрешение прерываний
BCF INTCON, PEIE ;BCF/BSF = DIS/ENABLE Разрешение прерываний от переферийных модулей

MOVF_F TMR1L, TIME_LO ;; FINALY, COPY TIMER1 INTO LO/HI BYTES.
MOVF_F TMR1H, TIME_HI

LOADF MS_TIME, .250 ;; 1 SEC DELAY BEFORE NEXT MEASUREMENT.
CALL MS_DELAY
CALL MS_DELAY
CALL MS_DELAY
CALL MS_DELAY
RETURN
;---------------------------------------

;Отсылаем данные в RS232
SEND_USART:
CALL TXWAIT
MOVF_F TIME_HI, TXREG
CALL TXWAIT
MOVF_F TIME_LO, TXREG
CALL TXWAIT
RETURN
;---------------------------------------

;Использовать эту задержку перед отправкой данных TXREG.
TXWAIT:
BANK1
BTFSS TXSTA, TRMT ;; IF TX IS COMPLETED,
GOTO $ - 1 ;; ELSE, WAIT
BANK0 ;; THEN, CONTINUE.
LOADF MS_TIME, .1
CALL MS_DELAY
RETURN
;--------------------------------------

;Вычисление скорости и вывод на LCD
LCD_UPDATE:
CALL CLEAR
MOVF_F TIME_HI, HI_BYTE
MOVF_F TIME_LO, LO_BYTE
CALL HEX16_TO_DEC5 ;; CONVERT HEX TO DECIMAL,
CALL DEC_TO_LCD ;; THEN DECIMAL TO LCD DISPLAY.

MEM_LCD_OUT TEN_K
MEM_LCD_OUT THOU
CHR_LCD_OUT '.'
MEM_LCD_OUT HUND
MEM_LCD_OUT TENS
MEM_LCD_OUT ONES
CHR_LCD_OUT 'm'
CHR_LCD_OUT 's'

; CALL LCD_TO_DEC
;; CALCULATIONS TO METERS PER SECOND.
; LOADF BIT8, .40 ;; DETECTOR DISTANCE = 40 MILLI-METERS
; CALL MUL_BY_1000 ;; MULTIPLY DISTANCE MILLI-METERS BY 1000
;
; MOVF_F HI16, DIVIDEND1 ;; DIVIDE MILLI-METERS BY TIMING
; MOVF_F LO16, DIVIDEND2 ;; 40,000 / TIME_HI:TIME_LO

LOADF DIVIDEND1, 0x9C ;; Для дистанции 40мм
LOADF DIVIDEND2, 0x40 ;; 40,000 / TIME_HI:TIME_LO

MOVF_F TIME_HI, DIVISOR1
MOVF_F TIME_LO, DIVISOR2
CALL DIVIDE_16_16 ;; RETURNS DIVIDEND+0:DIVIDEND+1

MOVF_F DIVIDEND+0, HI_BYTE ;; VELOCITY RESULT COPY
MOVF_F DIVIDEND+1, LO_BYTE ;; VELOCITY RESULT COPY
CALL HEX16_TO_DEC5
CALL DEC_TO_LCD

LOADF CHAR, 0X40 ;; GOTO LCD SECOND LINE.
CALL SET_ADDRESS

CHR_LCD_OUT ' '
MEM_LCD_OUT THOU ;; DISPLAY "XXXXX M/S"
MEM_LCD_OUT HUND
MEM_LCD_OUT TENS
MEM_LCD_OUT ONES
CHR_LCD_OUT 'm'
CHR_LCD_OUT '/'
CHR_LCD_OUT 's'

; CALL LCD_TO_DEC
RETURN
;---------------------------------------

;BORROWED FROM MICROCHIP APP NOTES. EXTENSIVELY
;MODIFIED TO SUPPORT 16F628.
;DIVIDE 16BIT BY 16BIT
;INPUT : DVDEND_HI, DVDEND_LO, DVSOR_HI, DVSOR_LO
;OUTPUT: DIVIDEND+0, DIVIDEND+1
;----Define divide register variables---
; ACC EQU 0x5C ; Most significant Byte
; SIGN EQU 0x62 ; save location for sign in MSB
; TEMP EQU 0x68 ; temporary storage
; DIVIDEND EQU 0x5C ; Most significant Byte
; DIVISOR EQU 0x65 ; Most significant Byte
; REMAIN EQU 0x60 ; Most significant Byte
; LOOPCOUNT EQU 0x63 ; loop counter
;---------------------------------------
DIVIDE_16_16:
MOVF_F DIVIDEND1, DIVIDEND+0
MOVF_F DIVIDEND2, DIVIDEND+1
MOVF_F DIVISOR1, DIVISOR+0
MOVF_F DIVISOR2, DIVISOR+1
CLRF REMAIN+0
CLRF REMAIN+1
MOVLW .16
MOVWF LOOPCOUNT
LOOP1616:
RLF ACC+0, W
RLF REMAIN+1, F
RLF REMAIN+0, F
MOVF DIVISOR+1, W
SUBWF REMAIN+1, F
MOVF DIVISOR+0, W
BTFSS STATUS, C
INCFSZ DIVISOR+0, W
SUBWF REMAIN+0, F
BTFSC STATUS, C
GOTO CONT1616
MOVF DIVISOR+1, W
ADDWF REMAIN+1, F
MOVF DIVISOR+0, W
BTFSC STATUS, C
INCFSZ DIVISOR+0, W
ADDWF REMAIN+0, F
BCF STATUS, C
CONT1616:
RLF ACC+1, F
RLF ACC+0, F
DECFSZ LOOPCOUNT, F
GOTO LOOP1616
RETURN
;---------------------------------------

;MULTIPY 8-BIT BY 1000
;INPUT = BIT8, ;OUTPUT = HI16, LO16
;MUL_BY_1000:
; CLRF HI16
; CLRF LO16
; MOVF_F BIT8, TEMP_MUL
; LOADF CNT1, .100
; LOADF CNT2, .10
;MUL1
; MOVF TEMP_MUL, W
; ADDWF LO16, F
; BTFSS STATUS, C ;; IF CARRY IS SET,
; GOTO $ + 2 ;; ELSE: SKIP
; INCF HI16, F ;; THEN: PROCESS
;
; DECFSZ CNT1, F
; GOTO MUL1
; LOADF CNT1, .100
; DECFSZ CNT2, F
; GOTO MUL1
; RETURN
;---------------------------------------

;CONVER 16BIT HEX INTO 5 DIGIT BCD
;INPUT : HI_BYTE, LO_BYTE
;OUTPUTS: TEN_K, THOU, HUND, TENS, ONES
HEX16_TO_DEC5:
MOVF_F HI_BYTE, NUMH ;; MOVF f,d Пересылка регистра F
MOVF_F LO_BYTE, NUML

SWAPF NUMH,W ;; SWAPF f,d Обмен местами тетрад в f
ANDLW 0X0F ;; ANDLW k Логическое "И" константы и W
ADDLW 0XF0 ;; ADDLW k Сложение константы с W
MOVWF THOU ;; MOVWF f Пересылка W в F
ADDWF THOU,F ;; ADDWF f,d Сложение W с f
ADDLW .226 ;; ADDLW k Сложение константы с W
MOVWF HUND ;; MOVWF f Пересылка W в F
ADDLW .50 ;; ADDLW k Сложение константы с W
MOVWF ONES ;; MOVWF f Пересылка W в F
MOVF NUMH,W ;; MOVF f,d Пересылка регистра F
ANDLW 0X0F ;; ANDLW k Логическое "И" константы и W
ADDWF HUND,F ;; ADDWF f,d Сложение W с f
ADDWF HUND,F ;; ADDWF f,d Сложение W с f
ADDWF ONES,F ;; ADDWF f,d Сложение W с f
ADDLW .233 ;; ADDLW k Сложение константы с W
MOVWF TENS ;; MOVWF f Пересылка W в F
ADDWF TENS,F ;; ADDWF f,d Сложение W с f
ADDWF TENS,F ;; ADDWF f,d Сложение W с f
SWAPF NUML,W ;; SWAPF f,d Обмен местами тетрад в f
ANDLW 0X0F ;; ANDLW k Логическое "И" константы и W
ADDWF TENS,F ;; ADDWF f,d Сложение W с f
ADDWF ONES,F ;; ADDWF f,d Сложение W с f
RLF TENS,F ;; RLF f,d Вращение f влево через перенос
RLF ONES,F ;; RLF f,d Вращение f влево через перенос
COMF ONES,F ;; COMF f,d Инверсия регистра f
RLF ONES,F ;; RLF f,d Вращение f влево через перенос
MOVF NUML,W ;; MOVF f,d Пересылка регистра F
ANDLW 0X0F ;; ANDLW k Логическое "И" константы и W
ADDWF ONES,F ;; ADDWF f,d Сложение W с f
RLF THOU,F ;; RLF f,d Вращение f влево через перенос
MOVLW 0X07 ;; MOVLW k Пересылка константы в W
MOVWF TEN_K ;; MOVWF f Пересылка W в F
MOVLW .10 ;; MOVLW k Пересылка константы в W
HD1:
ADDWF ONES,F ;; ADDWF f,d Сложение W с f
DECF TENS,F ;; DECF f,d Декремент регистра f
BTFSS 3,0 ;; BTFSS f,b Пропустить команду, если бит b=1
GOTO HD1 ;; GOTO k Переход по адресу
HD2:
ADDWF TENS,F ;; ADDWF f,d Сложение W с f
DECF HUND,F ;; DECF f,d Декремент регистра f
BTFSS 3,0 ;; BTFSS f,b Пропустить команду, если бит b=1
GOTO HD2 ;; GOTO k Переход по адресу
HD3:
ADDWF HUND,F ;; ADDWF f,d Сложение W с f
DECF THOU,F ;; DECF f,d Декремент регистра f
BTFSS 3,0 ;; BTFSS f,b Пропустить команду, если бит b=1
GOTO HD3 ;; GOTO k Переход по адресу
HD4:
ADDWF THOU,F ;; ADDWF f,d Сложение W с f
DECF TEN_K,F ;; DECF f,d Декремент регистра f
BTFSS 3,0 ;; BTFSS f,b Пропустить команду, если бит b=1
GOTO HD4 ;; GOTO k Переход по адресу
RETURN
;---------------------------------------

;PREREQUISITE: LOAD THOU, HUND, TENS, ONES
;
;LCD_TO_DEC:
; MOVLW 0X30
; SUBWF TEN_K, F
; SUBWF THOU, F
; SUBWF HUND, F
; SUBWF TENS, F
; SUBWF ONES, F
; RETURN
;---------------------------------------

;PREREQUISITE: LOAD TEN_K, THOU, HUND, TENS, ONES
;
DEC_TO_LCD:
MOVLW 0X30
ADDWF TEN_K, F
ADDWF THOU, F
ADDWF HUND, F
ADDWF TENS, F
ADDWF ONES, F
RETURN
;-----------------------------------------------

; LCD DRIVER AND COMMANDS FOR 4-BIT INTERFACE
;-----------------------------------------------
;PREREQUISITES: E, RS - OUTPUT
; PORTB 4-7 - OUTPUT
; MS_DELAY - SUBROUTINE
INIT_LCD:
LOADF MS_TIME, .40
CALL MS_DELAY ;; FUNCTION SET
BCF RS ;; SET LCD TO COMMAND MODE
LOADF PORTB, B'00100000'
CALL PULSE_E
LOADF PORTB, B'00100000'
CALL PULSE_E
LOADF PORTB, B'10000000'
CALL PULSE_E
LOADF MS_TIME, .1 ;; DISPLAY CONTROL
CALL MS_DELAY
LOADF PORTB, B'00000000'
CALL PULSE_E
LOADF PORTB, B'11110000'
CALL PULSE_E
LOADF MS_TIME, .1 ;; CLEAR DISPLAY
CALL MS_DELAY
LOADF PORTB, B'00000000'
CALL PULSE_E
LOADF PORTB, B'00010000'
CALL PULSE_E
LOADF MS_TIME, .1 ;; ENTRY MODE SET, .2
CALL MS_DELAY
LOADF PORTB, B'00000000'
CALL PULSE_E
LOADF PORTB, B'01100000'
CALL PULSE_E

LOADF MS_TIME, .2
CALL MS_DELAY

CALL BLINK_OFF
CALL CURSOR_OFF
RETURN

PULSE_E:
BSF E
GOTO $ + 1
GOTO $ + 1
GOTO $ + 1
BCF E
LOADF MS_TIME, .1
CALL MS_DELAY
RETURN
;-------------------------------------------

;INPUT : CHAR, 'X'
;OUTPUT: SENDS THE CHARACTER TO THE LCD
;SEND_CHAR:
; BSF RS ;; SET LCD TO CHARACTOR MODE
; MOVF CHAR, W
; MOVWF PORTB
; CALL PULSE_E
; SWAPF CHAR, W
; MOVWF PORTB
; CALL PULSE_E
; RETURN
;---------------------------------------

;INPUT : CHAR, 'X'
;OUTPUT: SENDS THE COMMAND TO THE LCD
SEND_CHAR:
BSF RS ;; SET LCD TO CHARACTOR MODE
GOTO $ + 2
SEND_COMM:
BCF RS ;; SET LCD TO COMMAND MODE
MOVF CHAR, W
MOVWF PORTB
CALL PULSE_E
SWAPF CHAR, W
MOVWF PORTB
CALL PULSE_E
RETURN
;---------------------------------------

CLEAR:
LOADF CHAR, B'00000001'
CALL SEND_COMM
LOADF MS_TIME, .2
CALL MS_DELAY
RETURN

;HOME:
; LOADF CHAR, B'00000010'
; CALL SEND_COMM
; LOADF MS_TIME, .2
; CALL MS_DELAY
; RETURN

SET_ADDRESS:
BSF CHAR, 7
CALL SEND_COMM
RETURN

BLINK_OFF:
LOADF CHAR, B'00001110'
CALL SEND_COMM
RETURN

CURSOR_OFF:
LOADF CHAR, B'00001100'
CALL SEND_COMM
RETURN
;---------------------------