;LAST UPDATE: 22.03.2014 savelij
 
 
 
;Receive array buf of max length with ending ZDLE sequence
 
; and CRC.  Returns the ending character or error code.
 
; NB: On errors may store length+1 bytes!
 
;НА ВХОДЕ: DE=ДЛИНА, HL=АДРЕС БУФЕРА
 
;НА ВЫХОДЕ: С=1 ЗАКОНЧИЛСЯ БУФЕР
 
ZRDATA          LD A,(rxframeind)
 
                CP ZBIN32
 
                JR NZ,ZM_0072
 
                RET;JP ZRDAT32
 
                
 
ZM_0072         CALL ZDLREAD
 
                DEC B
 
                JR Z,ZM_0078
 
                LD (HL),A
 
                INC HL
 
                CALL UPDCRC
 
                DEC DE
 
                LD A,D
 
                OR E
 
                JR NZ,ZM_0072
 
                LD (ADR_BUFRECV),HL
 
                LD A,ERROR
 
                RET
 
 
 
;crcfoo
 
ZM_0078         LD (ADR_BUFRECV),HL
 
                LD HL,zmblkmax
 
                AND A
 
                SBC HL,DE
 
                LD (rxcount),HL
 
                CP ZDLE
 
                RET Z
 
                CP LOW (GOTCRCE)
 
                JR Z,ZM_0080
 
                CP LOW (GOTCRCG)
 
                JR Z,ZM_0080
 
                CP LOW (GOTCRCQ)
 
                JR Z,ZM_0080
 
                CP LOW (GOTCRCW)
 
                JR Z,ZM_0080
 
                LD A,ZCAN
 
                RET
 
 
 
ZM_0080         PUSH AF
 
                CALL UPDCRC
 
                CALL ZDLREAD
 
                CALL UPDCRC
 
                CALL ZDLREAD
 
                CALL UPDCRC
 
                POP AF
 
                LD C,A
 
                LD HL,(CRC16_WORD)
 
                LD A,H
 
                OR L
 
                LD A,C
 
                RET
 
 
 
;Read a ZMODEM header to hdr, either binary or hex.
 
;eflag controls local display of non zmodem characters:
 
;    0:  no display
 
;    1:  display printing characters only
 
;    2:  display all non ZMODEM characters
 
;On success, set Zmodem to 1, set rxpos and return type of header.
 
; Otherwise return negative on error.
 
; Return ERROR instantly if ZCRCW sequence, for fast error recovery.
 
ZGETHDR         LD A,(rxtype)
 
                LD (prev_rxtype),A
 
                XOR A
 
                LD (rxtype),A
 
                LD (rxframeind),A
 
;again
 
ZM_0113         CALL RS232_READ
 
                CP ZPAD
 
                JR Z,ZM_0115
 
                CP ZPAD|0X80
 
                JR NZ,ZM_0118
 
                LD (Not8bit),A
 
                JR ZM_0115
 
 
 
ZM_0118         INC A
 
                RET Z
 
                CP ZPAD
 
                JR NZ,ZM_0113
 
;gotcan
 
                JR $
 
 
 
;garbage
 
ZM_0115         CALL NOXRD7
 
                CP ZDLE
 
                JR Z,ZM_0133
 
                CP ZPAD
 
                JR Z,ZM_0115
 
ZM_0133         CALL NOXRD7
 
                CP ZBIN
 
                JR NZ,ZM_0140
 
                LD (rxframeind),A
 
                CALL ZRBHDR
 
                LD A,(rxtype)
 
                RET
 
 
 
ZM_0140         CP ZBIN32
 
                JR NZ,ZM_0141
 
                LD (rxframeind),A
 
                JR $
 
 
 
ZM_0141         CP ZHEX
 
                JR NZ,ZM_0143
 
                LD (rxframeind),A
 
                CALL ZRHHDR
 
                LD A,(rxtype)
 
                RET
 
 
 
ZM_0143         CP ZDLE
 
                JR NZ,ZM_0113
 
                RET
 
 
 
;Receive a binary style header (type and position)
 
ZRBHDR          LD DE,0
 
                LD (CRC16_WORD),DE
 
                CALL ZDLREAD
 
                LD (rxtype),A
 
                CALL UPDCRC
 
                LD HL,rxhdr
 
                CALL ZDLREAD    ;1
 
                LD (HL),A
 
                INC HL
 
                CALL UPDCRC
 
                CALL ZDLREAD    ;2
 
                LD (HL),A
 
                INC HL
 
                CALL UPDCRC
 
                CALL ZDLREAD    ;3
 
                LD (HL),A
 
                INC HL
 
                CALL UPDCRC
 
                CALL ZDLREAD    ;4
 
                LD (HL),A
 
                INC HL
 
                CALL UPDCRC
 
                CALL ZDLREAD    ;1
 
                CALL UPDCRC
 
                CALL ZDLREAD    ;2
 
                CALL UPDCRC
 
                LD HL,(CRC16_WORD)
 
                LD A,H
 
                OR L
 
                LD A,(rxtype)
 
                RET
 
 
 
;Read a byte, checking for ZMODEM escape encoding
 
; including CAN*5 which represents a quick abort
 
;НА ВЫХОДЕ: B=0-ПРИНЯТ БАЙТ
 
;           B=1-ПРИНЯТ УПРАВЛЯЮЩИЙ БАЙТ
 
ZDLREAD         LD B,0
 
ZM_0359         CALL RS232_READ
 
                LD C,A
 
                AND 0X60
 
                LD A,C
 
                RET NZ
 
                CP ZDLE
 
                JR Z,ZM_0233
 
                CP 0X11
 
                JR Z,ZM_0359
 
                CP 0X13
 
                JR Z,ZM_0359
 
                CP 0X91
 
                JR Z,ZM_0359
 
                CP 0X93
 
                JR Z,ZM_0359
 
                LD A,(zctlesc)
 
                AND A
 
                LD A,C
 
                RET Z
 
                AND 0X60
 
                LD A,C
 
                JR Z,ZM_0359
 
                RET
 
 
 
;again2
 
ZM_0233         CALL RS232_READ
 
                CP ZDLE
 
                JR NZ,ZM_0248
 
                CALL RS232_READ
 
ZM_0248         CP ZDLE
 
                JR NZ,ZM_0252
 
                CALL RS232_READ
 
ZM_0252         CP ZDLE
 
                JR NZ,ZM_0256
 
                CALL RS232_READ
 
ZM_0256         LD C,A
 
                CP ZFREECNT
 
                JR Z,ZM_0233
 
                CP ZSTDERR
 
                JR Z,ZM_0233
 
                LD B,1
 
                CP ZDLE
 
                RET Z
 
                CP ZCRCE
 
                RET Z
 
                CP ZCRCG
 
                RET Z
 
                CP ZCRCQ
 
                RET Z
 
                CP ZCRCW
 
                RET Z
 
                DEC B
 
                CP 0X91
 
                JR Z,ZM_0260
 
                CP 0X93
 
                JR NZ,ZM_0263
 
ZM_0261         LD A,0XFF
 
                RET
 
 
 
ZM_0260         LD A,0X7F
 
                RET
 
 
 
ZM_0263         LD A,(zctlesc)
 
                AND A
 
                LD A,C
 
                JR Z,ZM_0265
 
                AND 0X60
 
                JR Z,ZM_0233
 
ZM_0265         LD A,C
 
                AND 0X60
 
                XOR 0X40
 
                RET NZ
 
ZM_0268         LD A,C
 
                XOR 0X40
 
                RET
 
 
 
;Receive a hex style header (type and position)
 
ZRHHDR          LD DE,0
 
                LD (CRC16_WORD),DE
 
                CALL ZGETHEX
 
                LD (rxtype),A
 
                CALL UPDCRC
 
                LD HL,rxhdr
 
                CALL ZGETHEX    ;1
 
                LD (HL),A
 
                INC HL
 
                CALL UPDCRC
 
                CALL ZGETHEX    ;2
 
                LD (HL),A
 
                INC HL
 
                CALL UPDCRC
 
                CALL ZGETHEX    ;3
 
                LD (HL),A
 
                INC HL
 
                CALL UPDCRC
 
                CALL ZGETHEX    ;4
 
                LD (HL),A
 
                CALL UPDCRC
 
                CALL ZGETHEX    ;1
 
                CALL UPDCRC
 
                CALL ZGETHEX    ;2
 
                CALL UPDCRC
 
                LD HL,(CRC16_WORD)
 
                LD A,H
 
                OR L
 
                RET NZ
 
                CALL RS232_READ
 
                CP 0X0D
 
                JR Z,ZM_0193
 
                CP 0X8D
 
                JR NZ,ZM_0195
 
                LD (Not8bit),A
 
ZM_0193         CALL RS232_READ
 
                CP 0X0A
 
                JR NZ,ZM_0195
 
                LD HL,Not8bit
 
                OR (HL)
 
                LD (HL),A
 
ZM_0195         LD A,(rxtype)
 
                AND A
 
                RET
 
 
 
;Decode two lower case hex digits into an 8 bit byte value
 
ZGETHEX         CALL NOXRD7
 
                BIT 7,A
 
                SCF
 
                RET NZ
 
                SUB '0'
 
                CP 10
 
                JR C,ZGETHEX1
 
                AND %11011111
 
                SUB 7
 
ZGETHEX1        RRCA
 
                RRCA
 
                RRCA
 
                RRCA
 
                AND 0XF0
 
                LD E,A
 
                CALL NOXRD7
 
                BIT 7,A
 
                SCF
 
                RET NZ
 
                SUB '0'
 
                CP 10
 
                JR C,ZGETHEX2
 
                AND %11011111
 
                SUB 7
 
ZGETHEX2        AND 0X0F
 
                OR E
 
                RET
 
 
 
;Read a character from the modem line with timeout.
 
;Eat parity, XON and XOFF characters.
 
NOXRD7          CALL RS232_READ
 
                AND 0X7F
 
                LD C,A
 
                CP XON
 
                JR Z,NOXRD7
 
                CP XOFF
 
                JR Z,NOXRD7
 
                CP 0X0A
 
                RET Z
 
                CP 0X0D
 
                RET Z
 
                CP ZDLE
 
                RET Z
 
                LD A,(zctlesc)
 
                AND A
 
                LD A,C
 
                RET Z
 
                LD A,C
 
                AND 0X60
 
                JR Z,NOXRD7
 
                LD A,C
 
                RET
 
 
 
;Send ZMODEM HEX header hdr of type type
 
;A=type
 
ZSHHDR          LD (tryzhdrtype),A
 
                LD A,ZPAD
 
                CALL RS232_WRITE
 
                LD A,ZPAD
 
                CALL RS232_WRITE
 
                LD A,ZDLE
 
                CALL RS232_WRITE
 
                LD A,ZHEX
 
                CALL RS232_WRITE
 
                LD A,(tryzhdrtype)
 
                CALL TO_HEX
 
                LD E,A
 
                XOR A
 
                LD D,A
 
                LD (CRC16_WORD),DE
 
                CALL TO_HEX
 
                CALL UPDCRC
 
                CALL TO_HEX
 
                CALL UPDCRC
 
                CALL TO_HEX
 
                CALL UPDCRC
 
                LD A,(txhdr+3)
 
                CALL TO_HEX
 
                CALL UPDCRC
 
                XOR A
 
                CALL UPDCRC
 
                CALL UPDCRC
 
                LD DE,(CRC16_WORD)
 
                LD A,D
 
                CALL TO_HEX
 
                LD A,E
 
                CALL TO_HEX
 
                LD A,0X0D
 
                CALL RS232_WRITE
 
                LD A,0X8A
 
                CALL RS232_WRITE
 
                LD A,(tryzhdrtype)
 
                CP ZFIN
 
                RET Z
 
                CP ZACK
 
                RET Z
 
                LD A,0X11
 
                JP RS232_WRITE
 
 
 
;ПЕРЕДАЧА БАЙТА В HEX ВИДЕ
 
TO_HEX          LD B,A
 
                RRCA
 
                RRCA
 
                RRCA
 
                RRCA
 
                CALL TO_HEX1
 
TO_HEX1         AND 0X0F
 
                CP 0X0A
 
                JR C,TO_HEX2
 
                ADD A,7
 
                OR %00100000
 
TO_HEX2         ADD A,'0'
 
                CALL RS232_WRITE
 
                LD A,B
 
                RET
 
 
 
;A=БАЙТ ДЛЯ ОБНОВЛЕНИЯ CRC16
 
UPDCRC          EXX
 
                LD DE,(CRC16_WORD)
 
                LD B,A
 
                LD C,E
 
                LD L,D
 
                LD H,HIGH (CRC16_TABLE)
 
                LD A,(HL)
 
                XOR B
 
                LD E,A
 
                INC H
 
                LD A,(HL)
 
                XOR C
 
                LD D,A
 
                LD A,B
 
                LD (CRC16_WORD),DE
 
                EXX
 
                RET
 
 
 
;Store long integer pos in txhdr
 
STOHDR          LD HL,txhdr
 
                LD (HL),E
 
                INC HL
 
                LD (HL),D
 
                INC HL
 
                LD (HL),C
 
                INC HL
 
                LD (HL),B
 
                RET
 
 
 
;Recover a long integer from a header
 
RCLHDR          LD HL,rxhdr
 
                LD E,(HL)
 
                INC HL
 
                LD D,(HL)
 
                INC HL
 
                LD C,(HL)
 
                INC HL
 
                LD B,(HL)
 
                RET
 
 
 
;Output the attention string (if there is one).
 
RXATTN          LD HL,attn
 
RXATTN1         LD A,(HL)
 
                AND A
 
                RET Z
 
                CALL RS232_WRITE
 
                JR RXATTN1
 
 
 
;send cancel string to get the other end to shut up
 
ABORTTX         LD E,10
 
ABORTTX1        LD A,0X18
 
                CALL RS232_WRITE                ;ПЕРЕДАЧА БАЙТА
 
                DEC E
 
                JR NZ,ABORTTX1
 
                LD E,10
 
ABORTTX2        LD A,8
 
                CALL RS232_WRITE                ;ПЕРЕДАЧА БАЙТА
 
                DEC E
 
                JR NZ,ABORTTX2
 
                RET