Lprint #19
21 сентября 1997

Программирование - Драйвер CDOS-модема.

<b>Программирование</b> - Драйвер CDOS-модема.
┌----------------------------------------┐
│░░░░░░░░░░ Драйвер CDOS модема ░░░░░░░░░│
└----------------------------------------┘
                                          
LPR> В шестом номере ZX-FORMAT, был  опубл
кован драйвер vicom'модема, он  отличается
от CDOS только битами. Но самое интересное
что ~скинуть~ этот драйвер  на  диск  было
невозможно, а переписать на бумажку 30  кБ
тексту тоже  нереально. Тогда-же  на  сети
появился первый призыв ~выдрать~ сей драй-
вер и вот, то что вы видите  и  есть  плод
симбиоза А.Никифорова и Stalker Debugger'а
:). ~Скидывайте~ этот и следующий  разделы
на диск, грузите  в  ZX-ASM, удаляйте  все
лишнее, Import'те и наконец ассемблируйте.
                                          
      ------------------------------      
           Д  Р  А  Й  В  Е  Р            
         ------------------------         
                                          
;               Внимание!                 
;   В программе Macro Modem v2.20 функции 
;работы с часами/таймером не используются,
;они зарезервированы под будующие версии. 
                                          
CALLING EQU 01                            
                                          
;ФЛАГ РАЗРЕШЕНИЯ НАБОРА НОМЕРА            
;ЕСЛИ "1", TO ДРАЙВЕР БУДЕТ НАБИРАТь      
;HOMEP И РЕАГИРОВАТь НА ЗВОНКИ            
;ЕСЛИ "0" - HE БУДЕТ, HO И HE БУДЕТ       
;ЗАВИСАТь ПРИ ОТСУТСТВИИ "ПРИБАМБАСА"     
                                          
        ORG #C000                         
                                          
;КЕРНАЛь ПОДПРОГРАММ                      
                                          
        JP D_INSTAL                       
        JP D_NAME                         
        JP D_RD_STAT                      
        JP D_WAIT_INS                     
        JP D_WAIT_LN                      
        JP D_WAIT_BLC                     
        JP D_TRANSMIT                     
        JP D_ON_LINE                      
        JP D_OFF_LINE                     
        JP D_CALL                         
        JP D_AON                          
        JP SET_CON_A                      
        JP SET_CON_P                      
        JP D_SET_TIME                     
        JP D_RD_TIME                      
        JP D_CAL_TIM                      
        JP D_SET_ALR                      
        JP D_ADD_ALR                      
        JP D_RD_ALR                       
                                          
;РАБОЧИЕ ПЕРЕМЕННЫЕ ДРАЙВЕРА              
                                          
LINE_STATUS DB 0                          
SPEED       DB 0                          
LCOUNT_A    DB 0                          
LCOUNT_B    DB 0                          
LCOUNT_C    DB 0                          
ZERO_BYTE   DB 0 ;БАЙТ ИДУЩИЙ ПЕРЕД       
                 ;ДЛИНОЙ В БЛОКЕ          
SYNC_TABL   DS 15                         
                                          
;УСТАНОВКА ДРАЙВЕРА                       
;in: [HL] АДРЕС БУФЕРА МОДЕМА             
;out: В БУФЕРЕ В ASCII ФОРМЕ ЗНАЧЕНИЯ     
;СКОРОСТЕЙ.                               
;НА КАЖДУЮ СКОРОСТь ПО 4 БАЙТА,           
;КОЛ-ВО СКОРОСТЕЙ 8, ЗАКАНЧИВАЕТСЯ #00    
                                          
D_INSTAL RET C                            
                                          
;ЕСЛИ ДРАВЕР ВЫЗЫВАЕТСЯ C УСТАНОВЛЕНЫМ    
;ФЛАГОМ CY - TO ЭТО ЗАПУСК ДЛЯ            
;РАСПАКОВКИ, И ЕГО ИГНОРИРУЕМ             
                                          
        LD (MOD_BUFF1),HL ;ЗАПИСАЛИ В     
        LD (MOD_BUFF2),HL ;НУЖНЫЕ МЕСТА   
        LD (MOD_BUFFЗ),HL ;АДРЕС          
        LD (MOD_BUFFЧ),HL ;БУФЕРА         
                                          
;ПЕРЕБРАСЫВАЕМ В БУФЕР СКОРОСТИ ДРАЙВЕРА  
                                          
        EX DE,HL                          
        LD HL,SPD_MODEM                   
        LD BC,ESPD_MODEM-SPD_MODEM        
        LDIR                              
        RET                               
                                          
SPD_MODEM                                 
        DB " 600 ","1800 ","2400 "        
        DS 5*5                            
ESPD_MODEM                                
                                          
;ЧТЕНИЕ ИНФОРМАЦИИ O ДРАЙВЕРЕ             
;out: ПО [DE] ЗАПИСЫВАЕТСЯ НАЗВАНИЕ       
;ДРАЙВЕРА (ДО 80-ТИ СИМВОЛОВ),            
;ЗАКАНЧИВАЕТСЯ КОДОМ #00                  
                                          
D_NAME   LD HL,NAME_MODEM                 
         LD BC,ENAME_MODEM-NAME_MODEM     
         LD DE,(MOD_BUFF1)                
         LDIR                             
         RET                              
                                          
NAME_MODEM                                
        DB "Vicomm-modem driver v1.04  "  
        DB "(C) 1997 *MAS*",0             
ENAME_MODEM                               
                                          
;ЧТЕНИЕ СТАТУСА ЛИНИИ/ДРАЙВЕРА            
;in: [A] ЦВЕТ БОРДЮРА                     
;out: [A] - ДАННЫЕ ДЛЯ ПОРТА #FE          
;     T.К. ЦВЕТ БОРДЮРА + БИТЫ УПРАВЛЕНИЯ 
;     ЛИНИЕЙ И ВЫХОД ЛИНИИ                
;[B]: ПО БИТАМ:                           
;   0 СТАТУС ЛИНИИ (СВОБОДНА/ЗАНЯТА)      
;   3 наличие тонового набора             
;   4 ВЫКЛЮЧАТь TURBO ПРИ ВЫЗОВЕ ДРАЙВЕРА 
;   5 УПРАВЛЕНИЕ ЛИНИЕЙ                   
;   6 НАЛИЧИЕ ТАЙМЕРА                     
;   7 НАЛИЧИЕ ЧАСОВ                       
                                          
D_RD_STAT                                 
        AND 7: LD C,A                     
        LD A,(LINE_STATUS)                
        LD B,A: OR C                      
        OUT (#FE),A: LD (BORDER_0+1),A    
        OR  #08: LD (BORDER_1+1),A        
        PUSH AF                           
        XOR A: INC B: DEC B               
        JR Z,$+3: INC A                   
                                          
      IF CALLING                          
                                          
;ВЫКЛЮЧАТь TURBO, ECTb УПРАВЛЕНИЕ ЛИНИЕЙ, 
;HET ЧАСОВ, ТАЙМЕРА                       
                                          
        OR %00110000                      
                                          
      ELSE                                
                                          
;ВЫКЛЮЧАТь TURBO, HET УПРАВЛЕНИЯ ЛИНИЕЙ,  
;HET ЧАСОВ, ТАЙМЕРА, ТРУБКА СНЯТА         
                                          
        OR %00010001                      
      ENDIF                               
        LD B,A                            
        POP AF: RET                       
                                          
;СНЯТь ТРУБКУ                             
                                          
D_ON_LINE  LD A,#20: JR ON_OFF_L          
                                          
;ПОЛОЖИТь ТРУБКУ                          
                                          
D_OFF_LINE XOR A                          
                                          
ON_OFF_L                                  
                                          
;ИЗМЕНЕНИЕ СТАТУСА ЛИНИИ, ЕСЛИ HET        
;УПРАВЛЕНИЯ ЛИНИЕЙ - СРАЗУ ВОЗВРАТ        
                                          
      IF CALLING                          
         LD (LINE_STATUS),A               
         LD B,A: LD A,(BORDER_0+1)        
         OR B: LD (BORDER_0+1),A          
         OUT (#FE),A                      
         OR #08: LD (BORDER_1+1),A        
      ENDIF                               
         RET                              
                                          
;НАБРАТь HOMEP, ТРУБКА УЖЕ СНЯТА          
; in:                                     
; [HL] - АДРЕС БУФЕРА C HOMEPOM           
;  [A] - 0 pulse,  1 tone                 
;  [B] период импульса ms, станд. 100     
;  [C] межцифровая пауза ms/10            
; CY=1 ОШИБКА, КОД ОШИБКИ В [A]:          
;    0 ОШИБКА НАБОРА                      
;    1 HET ДЛИННОГО ГУДКА                 
;    2 ПРЕРЫВАНИЕ                         
; CY=0 СОЕДИНЕНИЕ УСТАНОВЛЕНО:            
;ВОЗВРАЩАЮТСЯ ДАННЫЕ КАК ИЗ SET_CON_P     
                                          
D_CALL                                    
      IF CALLING                          
        LD (ID_CALL+1),HL                 
        PUSH BC                           
                                          
;УСТАНАВЛИВАЕМ П/П СКАНИРОВАНИЯ ЛИНИИ     
                                          
        XOR A: CALL D_WAIT_INS            
        POP BC                            
        LD A,C: LD (CDEL_COD+1),A         
                                          
;ЗАДАН ПЕРИОД ИМПУЛьсА, ПО СТАНДАРТУ      
;ДАЕТСЯ 2/5 ПЕРИОДА ЛИНИЯ ЗАМКНУТА,       
;И 3/5 ПЕРИОДА ЛИНИЯ РАЗОМКНУТА           
;ДЕЛИМ ПЕРИОД НА 5                        
                                          
        LD A,B: LD B,0                    
DIVS    SUB 5: JR C,EDIVS                 
        INC B: JR DIVS                    
EDIVS   INC B: DEC B: JR NZ,$+3: INC B    
        LD A,B: RLCA    ;2/5 ПЕРИОДА      
        LD (CDEL_1+1),A                   
        ADD A,B         ;3/5 ПЕРИОДА      
        LD (CDEL_0+1),A                   
                                          
;ЗАПИСЫВАЕМ ЗНАЧЕНИЯ ВЫДАВАЕМЫЕ В ПОРТ    
;#FE ДЛЯ ЗАМЫКАНИЯ/РАЗМЫКАНИЯ ЛИНИИ       
                                          
        LD A,(BORDER_0+1): AND #0F        
        LD (DCAL_OFF+1),A                 
        LD A,(BORDER_1+1): OR #20         
        LD (DCAL_ON+1),A                  
                                          
;МАСЕНьКАЯ ПАУЗА ПЕРЕД НАБОРОМ            
                                          
        EI: LD B,45: HALT: DJNZ $-1       
                                          
;КОНТРОЛь ДЛИННОГО ГУДКА:                 
;ДЕЛАЕМ 200 ОПРОСОВ ЛИНИИ, ЕСЛИ           
;ПОЙМАЕМ 30 РАЗ ПОДРЯД ГУДОК - ВСЕ ОК     
                                          
         LD BC,200*256+30                 
WAIT_DIA CALL WAIT_CALL                   
         JR C,DWAIT_R   ;ГУДКА HET        
         DEC C                            
         JR Z,ID_CALL ;ПОЙМАЛИ 30 РАЗ     
         JR DWAIT_N                       
                                          
;ЕСЛИ XOTb РАЗ ПОТЕРЯЛИ ГУДОК - УСТАНО-   
;ВИТь СЧЕТЧИК ЗАНОВО НА 30                
                                          
DWAIT_R  LD C,30                          
                                          
;ЕСЛИ НАЖАТ ПРОБЕЛ - ВЫХОД                
                                          
DWAIT_N LD A,#7F: IN A,(#FE)              
        RRCA: JR NC,BRK_CALL              
        DJNZ WAIT_DIA                     
                                          
NO_DIAL   LD A,1: SCF: RET ;HET СИГНАЛА   
BRK_CALL  LD A,2: SCF: RET ;ПРЕРЫВАНИЕ    
ERRD_CALL XOR A: SCF: RET  ;ОШИБКА        
                                          
ED_CALL XOR A: RET ;HOMEP НАБРАН          
                                          
;СОБСТВЕННО НАБОР НОМЕРА                  
ID_CALL LD HL,0 ;ЗДЕСь БУДЕТ АДРЕС БУФЕРА 
        LD A,(HL): INC HL                 
        LD (ID_CALL+1),HL                 
        OR A         ;НАЙДЯ КОД #00       
        JR Z,ED_CALL ;ОКАНЧИВАЕМ НАБОР    
;СИМВОЛЫ "-", "(", ")", " " ИГНОРИРУЕМ    
        CP "-": JR Z,ID_CALL              
        CP "(": JR Z,ID_CALL              
        CP ")": JR Z,ID_CALL              
        CP " ": JR Z,ID_CALL              
        SUB "0": JR C,ERRD_CALL           
;ЕСЛИ ЭТО HE ЦИФРА - ОШИБКА НАБОРА        
                                          
;ЦИФРЕ "0" СООТВЕТСТВУЕТ 10 ИМПУЛьСОВ     
        JR NZ,$+4: LD A,10                
        CP 11: JR NC,ERRD_CALL            
        LD B,A                            
                                          
;НАБИРАЕМ ЦИФРУ, В [B] КОЛ-ВО ИМПУЛьСОВ   
                                          
CALL_C                                    
                                          
;РАЗРЫВ ЛИНИИ НА бOms (3/5)               
                                          
DCAL_OFF LD A,0                           
         OUT (#FE),A                      
                                          
CDEL_0   LD A,0                           
DDEL_0   LD C,248                         
         DEC C: JP NZ,$-1                 
         DEC A: JP NZ,DDEL_0              
                                          
;ЗАМЫКАНИЕ ЛИНИИ И ПАУЗА ЧOms (2/5)       
                                          
DCAL_ON LD A,0                            
        OUT (#FE),A                       
                                          
;ЗАДЕРЖКА НА [A] ms                       
                                          
CDEL_1  LD A,0                            
DDEL_1  LD C,248                          
        DEC C: JP NZ,$-1                  
        DEC A: JP NZ,DDEL_1               
                                          
         DJNZ CALL_C                      
                                          
;МЕЖЦИФРОВАЯ ПАУЗА В 6OOms                
                                          
CDEL_COD LD B,0                           
W_CDEL  NOP: NOP: LD DE,1457              
        DEC DE: LD A,D                    
        OR E: JP NZ,$-3                   
        DJNZ W_CDEL                       
                                          
;ЕСЛИ НАЖАТ ПРОБЕЛ - ВЫХОД,ИНАЧЕ НАБИРАЕМ 
;HOMEP ДАЛьШЕ                             
        LD A,#7F: IN A,(#FE)              
        RRCA: JR NC,BRK_CALL              
        JR ID_CALL                        
                                          
;ОПРАШИВАЕМ ЛИНИЮ 32 РАЗА                 
                                          
WAIT_CALL DI: PUSH BC                     
        LD B,32                           
        LD HL,0                           
                                          
CALL_DIAL LD DE,#0B59                     
         CALL SCAN_IN                     
         CALL DELAY_37                    
         LD E,A: LD D,0: ADD HL,DE        
         DJNZ CALL_DIAL                   
         POP BC                           
;КОНТРОЛь ГУДКА, СРЕДН. АРИФМ.            
;ЗНАЧЕНИЕ ЧАСТОТЫ ЗА 32 ОПРОСА            
        SRA H: RR L : SRA H: RR L         
        SRA H: RR L : SRA H: RR L         
        SRA H: RR L                       
        LD A,L: SRA A                     
                                          
;В ИНТЕРВАЛЕ 150...250 - ЧАСТОТА ГУДКА    
        CP 150: RET C                     
        CP 250: CCF                       
        RET                               
                                          
      ELSE                                
        XOR A: SCF: RET                   
      ENDIF                               
                                          
;ВЫЗЫВАЕТСЯ ПРИ ОБНАРУЖЕНИИ ЗВОНКА.       
;СНИМАЕТСЯ ТРУБКА. + ОПРЕДЕЛЕНИЕ НОМЕРА   
;(ЗДЕСь ОТСУТСТВУЕТ!)                     
                                          
;out: MOD_BUFF НОМЕР В ASCII, В КОНЦЕ 0   
                                          
D_AON   CALL D_ON_LINE                    
        LD B,75: EI: HALT: DJNZ $-2: DI   
;ПОСЛЕ СНЯТИЯ ТРУБКИ ПАУЗА В 1.5 СЕК.     
;ЕСЛИ ECTb АОН, TO OH МОЖЕТ ОПРЕДЕЛИТь    
;HOMEP                                    
                                          
;ПЕРЕБРАСЫВАЕМ В БУФЕР МОДЕМА СООБЩЕНИЕ   
;O СНЯТИИ ТРУБКИ                          
                                          
MOD_BUFFЗ EQU $+1: LD DE,#1111            
                                          
         LD HL,AON_TXT                    
         LD BC,EAON_TXT-AON_TXT           
         LDIR                             
         RET                              
                                          
AON_TXT                                   
    DB 13,"Модем подключен к линии",13,0  
EAON_TXT                                  
                                          
;ДВЕ НИЖЕСЛЕДУЮЩИЕ П/П ИСПОЛьЗУЮТСЯ       
;КАК "ЗАГЛУШКИ", T.К. АЛГОРИТМ АВТОВЫБОРА 
;СКОРОСТИ ЕЩЕ HE ОБДУМЫВАЛСЯ              
                                          
;установить соединение, передача          
;T.E. ВНАЧАЛЕ "ПЕРЕДАЕТ", ПОТОМ "СЛУШАЕТ" 
                                          
SET_CON_A                                 
                                          
;установить соединение, прием             
;T.E. ВНАЧАЛЕ "СЛУШАЕТ", ПОТОМ "ПЕРЕДАЕТ" 
                                          
SET_CON_P                                 
                                          
MOD_BUFFЧ EQU $+1: LD DE,0                
      IF CALLING                          
        PUSH HL                           
        LD (HL),13: LD BC,1: XOR A        
        CALL D_TRANSMIT                   
        POP HL                            
      ENDIF                               
                                          
;УСТАНОВКА СОЕДИНЕНИЯ                     
;В MOD_BUFF ВОЗВРАЩАЕТСЯ ТЕКСТОВОЕ СООБЩ. 
;O СОЕДИНЕНИИ, В КОНЦЕ - КОД #00          
;В [A] УСТАНОВЛЕНАЯ СКОРОСТь, ИЛИ #80     
;ЕСЛИ ОНА НЕОПРЕДЕЛЕНА                    
         LD HL,CARR_TXT                   
         LD BC,ECARR_TXT-CARR_TXT         
         LDIR                             
         LD A,#80 ;СКОРОСТь НЕОПРЕДЕЛЕНА  
         RET                              
                                          
CARR_TXT                                  
    DB 13,"Соедение установлено",13,0     
ECARR_TXT                                 
                                          
;ИНСТАЛЯЦИЯ ПЕРЕД СКАНИРОВАНИЕМ ЛИНИИ     
;В [A] - ГРОМКОСТь ВЫВОДА ЗВУКА ЛИНИИ     
;ЧЕРЕЗ AY                                 
                                          
D_WAIT_INS                                
        LD HL,#4000: LD (LCOUNT_A),HL     
        AND #0F: SET 6,A: LD (SOUND+1),A  
        JR Z,D_WAIT_INS1                  
         LD BC,#FFFD: LD A,7: OUT (C),A   
         LD B,#BF: LD A,#3F: OUT (C),A    
                                          
D_WAIT_INS1                               
        XOR A: LD (LAST_DT+1),A           
        LD (COUNTO+1),A                   
        LD (COUNT1+1),A                   
        LD (LASTO+1),A                    
        LD (OFFCOU+1),A                   
        RET                               
                                          
;СКАНИРОВАНИЕ ЛИНИИ                       
;out                                      
;CY=1: НИЧЕГО                             
; [B] КОЛИЧЕСТВО ЦИКЛОВ ОПРОСА            
; [C] СКОЛьКО ВСЕГО ДОЛЖНО БЫТь ЦИКЛОВ    
;CY=0, ;[A] - КОД:                        
;1 - ПРИНЯТ БЛОК, 2 - ЗАНЯТО, 3 - ВЫЗОВ   
                                          
D_WAIT_LN                                 
        DI                                
        LD HL,0                           
        LD DE,16*256+12  ;11              
        LD BC,#FFFD: LD A,8: OUT (C),A    
        LD A,(SOUND+1)                    
        AND #0F: JR Z,$+4: LD B,#BF       
                                          
;ОПРОС ЛИНИИ НА СИНХРОСИГНАЛ БЛОКА И      
;КОНТРОЛь КОТОТКИХ ГУДКОВ, ВНАЧАЛЕ        
;СЧИТАЕМ СРЕДН. АРИФМ. ЗНАЧЕНИЕ ЧАСТОТЫ   
;ЗА 16 ОПРОСОВ                            
                                          
MDLOOP1                                   
        IN A,(#FE): AND #20               
                                          
;АНАЛИЗ/HET СИГНАЛА ВЫЗОВА                
    IF CALLING                            
        JP Z,RING : ELSE: JP $+3          
    ENDIF                                 
                                          
        CALL IN_LINE_F                    
        CP 11: JP C,MDLOOP2               
        CP 89: JP NC,MDLOOP2              
        DEC E: JP Z,INPUT_BLOCK ;БЛОК?    
MDLOOP2 ADD A,L: LD L,A                   
        JR NC,$+3: INC H                  
        DEC D: JP NZ,MDLOOP1              
                                          
        SRA H: RR L : SRA H: RR L         
        SRA H: RR L : SRA H: RR L         
        LD A,L: SRA A                     
                                          
;В ИНТЕРВАЛЕ 150...250 - ЧАСТОТА ГУДКА    
;ЕСЛИ ГУДОК, TO А=1 ИНАЧЕ А=0             
        CP 150: JR C,TST_OFFL             
        CP 250: JR C,TST_ONL              
                                          
TST_OFFL XOR A: JR $+4                    
TST_ONL  LD A,1                           
                                          
;ЕСЛИ COCT. СИГНАЛА HE ИЗМЕНИЛОСь, TO     
;ПРОСТО УВЕЛИЧИТь СЧЕТЧИК. ЕСЛИ           
;ИЗМЕНИЛОСь, TO ПЕРЕКЛЮЧИТь СЧЕТЧИК       
                                          
LAST_DT  CP 0: LD (LAST_DT+1),A           
         JR NZ,NEW_DTL                    
                                          
ADR_IDL  LD HL,0: INC (HL): LD A,(HL)     
         CP 200: CALL NC,D_WAIT_INS1      
         JR E_WAIT_LN                     
                                          
;ЧАСТОТА ИЗМЕНИЛАСь:                      
                                          
NEW_DTL DEC A: JR Z,NEW_DTL1              
                                          
;СТАЛА "0": ПЕРЕКЛЮЧАЕМ СЧЕТЧИК           
        LD HL,COUNTO+1 : LD (HL),0        
        LD (ADR_IDL+1),HL                 
                                          
;ЕСЛИ БЫЛО >4 ЕДЕНИЦ И >4 НУЛЕЙ ПОДРЯД,   
;ЗНАЧИТ ПОЙМАЛИ СИГНАЛ ОТБОЯ              
                                          
COUNT1  LD A,0: CP 4: JP C,RES_OFF        
LASTO   LD A,0: CP 4: JP C,RES_OFF        
                                          
;ПОЙМАВ 3 ГУДКА ОТКЛЮЧИТСЯ                
                                          
OFFCOU  LD A,0: INC A: LD (OFFCOU+1),A    
        CP 3: JR Z,BUSY_FOUND             
                                          
;ЧАСТОТА СТАЛА "1": ПЕРЕКЛЮЧАЕМ СЧЕТЧИК   
NEW_DTL1 LD HL,COUNT1+1 : LD (HL),0       
        LD (ADR_IDL+1),HL                 
COUNTO  LD A,0                            
JPE_WAIT_LN LD (LASTO+1),A                
        JR E_WAIT_LN                      
                                          
RES_OFF XOR A                             
        LD (COUNTO+1),A                   
        LD (COUNT1+1),A                   
                                          
        JR JPE_WAIT_LN                    
                                          
BUSY_FOUND                                
        OR A: LD A,2 ;CY=0, A=2 "ЗАНЯТО"  
        RET                               
                                          
;ПОЙМАЛИ ЗВОНОК, ПРОВЕРКА НА РЕАЛьНОСТь   
;ЕСЛИ СИГНАЛ ВЫЗОВА БУДЕТ ДЕРЖАТьСЯ       
;НЕКОТОРОЕ ВРЕМЯ - ЗНАЧИТ ВЫЗОВ В НАТУРЕ  
                                          
RING    LD C,2                            
RING1   LD B,30: NOP: DJNZ $-1            
        IN A,(#FE): AND #20               
        JP NZ,D_WAIT_LN                   
        DEC C: JR NZ,RING1                
                                          
;ЗВОНОК ECTb, ОЖИДАЕМ ЕГО ОКОНЧАНИЯ       
                                          
RING2   IN A,(#FE): AND #20: JR Z,RING2   
        LD A,3   ;CY=0, A=3 "ЗВОНОК"      
        RET                               
                                          
E_WAIT_LN LD BC,#0101                     
          SCF: RET  ;CY=1 - НИЧЕГО HET    
                                          
;ОПРОС ВХОДА: В [A] БУДЕТ ЧАСТОТА СИГНАЛА 
                                          
IN_LINE_F PUSH HL: PUSH DE                
          LD DE,(LCOUNT_A)                
SOUND     LD L,0                          
                                          
LP_TIN_F INC E: JP Z,END_TIN_F            
         INC E: JP Z,END_TIN_F            
         IN A,(#FE)                       
          RLCA: RLCA: SBC A,A             
          AND L: NOP: OUT (C),A           
         AND #40: XOR D: JP Z,LP_TIN_F    
        XOR D: LD (LCOUNT_B),A            
                                          
RET_TIN_F LD A,E                          
        LD HL,LCOUNT_A                    
        SUB (HL): LD (HL),A               
        LD A,E                            
        POP DE: POP HL                    
        RET                               
                                          
END_TIN_F DEC E: JR RET_TIN_F             
                                          
;ПОЙМАЛИ СИНХРОСИГНАЛ, ПРИНИМАЕМ БЛОК     
                                          
INPUT_BLOCK                               
        CALL IN_LINE                      
        CALL CONTR_SPEED                  
        CALL LOAD_DATA                    
        RET C                             
                                          
E_LOAD_DT LD A,(SPEED): LD D,A            
BLOCK_LEN EQU $+1: LD BC,#0101            
;CY=0   УСПЕШНО ПРИНЯЛИ БЛОК              
          OR A: LD A,1                    
          RET                             
                                          
;ДОЛГОЕ ОЖИДАНИЕ БЛОКА И ПРИЕМ БЛОКА      
                                          
;out: CY HET БЛОКА                        
;[BC] ДЛИНА                               
;[D] СКОРОСТь (#80 НЕОПРЕДЕЛЕНА)          
                                          
D_WAIT_BLC                                
        CALL WAIT_LINE: RET C             
        CALL LOAD_DATA                    
        CALL LINE_FREE                    
        JR E_LOAD_DT                      
                                          
SCAN_IN CALL IN_LINE                      
        CP D : RET C                      
        CP E : CCF                        
        RET                               
                                          
IN_LINE_D    ;ЗАДЕРЖКА И ОПРОС ВХОДА      
        PUSH BC : POP BC                  
                                          
;ОПРОС ВХОДА                              
                                          
IN_LINE PUSH HL : PUSH BC                 
        LD A,(LCOUNT_A) : LD C,A          
        LD A,(LCOUNT_B) : LD B,A          
                                          
LOOP_TIN INC C : JP Z,END_TIN             
         IN A,(#FE) : AND #40             
         XOR B : JP Z,LOOP_TIN            
                                          
        XOR B : LD (LCOUNT_B),A           
RET_TIN LD A,C                            
        LD HL,LCOUNT_A                    
        SUB (HL) : LD (HL),A              
        LD A,C                            
        POP BC : POP HL                   
        RET                               
                                          
END_TIN DEC C: JR RET_TIN                 
                                          
;ОЖИДАНИЕ ОСВОБОЖДЕНИЯ ЛИНИИ, ВЕРТИМСЯ    
;ЗДЕСь ДО TEX ПОР, ПОКА ИЗ ЛИНИИ HE       
;ИСЧЕЗНЕТ СИГНАЛ АБОНЕНТА                 
                                          
LINE_FREE                                 
        PUSH AF : PUSH DE : PUSH BC       
        XOR A : LD (LCOUNT_A),A           
        LD A,#40 : LD (LCOUNT_B),A        
        CALL IN_LINE                      
        LD DE,#0570    ;#0180             
        NOP : NOP                         
LN_FREE1 NOP: NOP                         
LN_FREE2 LD B,4                           
         CALL DELAY_37                    
         CALL SCAN_IN                     
         NOP : JP  NC,LN_FREE1            
                                          
LN_FREEЗ DEC B : JP Z,LINE_FREEЧ          
        CP #FF : JP NC,LINE_FREEЧ         
        CALL DELAY_37                     
        CALL SCAN_IN                      
        JP C,LN_FREEЗ                     
        JP LN_FREE2                       
                                          
;ЛИНИЯ СВОБОДНА                           
                                          
LINE_FREEЧ                                
        POP BC : POP DE : POP AF          
        RET                               
                                          
;СИНХРОНИЗАЦИЯ БЛОКА                      
                                          
SYNCD1_IN JP SYNC1_IN                     
SYNC1_IN  NOP : NOP                       
        CALL IN_LINE                      
        CP D : JP C,ED_SYNCD              
        CP E : CCF: JP C,ED_SYNCD         
        LD B,A                            
        LD A,(HL)                         
        OR A : JP Z,SYNC1_I1              
        ADD A,B : LD (HL),A               
SYNC1_I2 ADD A,0                          
         INC HL                           
         RET                              
SYNC1_I1 JP SYNC1_I2                      
                                          
SYNCD2_IN JP SYNC2_IN                     
SYNC2_IN  NOP : NOP                       
SYNC2_I6 CALL IN_LINE                     
        CP D: JP C,ED_SYNCD               
        CP E: CCF: JP C,ED_SYNCD          
        LD B,A                            
        LD A,(HL)                         
        SUB B                             
        JP P,SYNC2_I2                     
        XOR A : ADD A,0                   
SYNC2_I1 LD (HL),A                        
         INC HL                           
         RET                              
SYNC2_I2 JP SYNC2_I1                      
                                          
ED_SYNCD INC SP : INC SP                  
ERR_SYNC POP DE : POP HL                  
         RET                              
                                          
;ЗАДЕРЖКИ НА СООТВ. ЧИСЛО ТАКТОВ          
DELAY_57   JP DELAY_47                    
DELAY_47   JP DELAY_37                    
DELAY_37   CALL DELAY_27                  
DELAY_27   RET                            
DELAY_68   CALL DELAY_27                  
           CALL DELAY_27                  
           NOP                            
           RET                            
                                          
DELAY_C LD B,#FE                          
         CALL DELAY_47                    
         CALL DELAY_47                    
        DJNZ DELAY_C+2                    
        DEC C : JP NZ,DELAY_C             
        RET                               
                                          
;ОЖИДАНИЕ СИГНАЛА АБОНЕНТА                
;В ТЕЧЕНИИ 2...4 СЕКУНД                   
                                          
WAIT_LINE DI                              
          LD HL,#4000 : LD (LCOUNT_A),HL  
          LD D,3                          
WT_LINE1 LD E,3                           
WT_LINE2 LD H,1                           
WT_LINEЗ LD B,16                          
         LD A,H: LD (LCOUNT_C),A          
LP_WLINE CALL IN_LINE                     
         CP MIN+1 : JP C,WAIT_CONTR1      
         CP #2D : JP C,WAIT_SPEED         
WAIT_CONTR                                
         ADD A,L : JP NC,$+4 : INC H      
         ADD A,6 : LD L,A                 
         JP NC,$+4 : INC H                
         LD A,(LCOUNT_C)                  
         CP H                             
         JP C,WT_LINEЗ                    
         JP Z,WAIT_CONTR2                 
         DEC E : JP NZ,WT_LINE2           
         DEC D : JP NZ,WT_LINE1           
         SCF: RET                         
                                          
WAIT_CONTR1 CP 5                          
            JP WAIT_CONTR                 
                                          
WAIT_CONTR2 LD B,16                       
            JP LP_WLINE                   
                                          
;КОНТРОЛь СКОРОСТИ ПРИ ОЖИДАНИИ           
                                          
WAIT_SPEED                                
        CALL DELAY_47: NOP                
        DEC B : JP NZ,LP_WLINE            
        CALL IN_LINE                      
                                          
;КОНТРОЛь СКОРОСТИ. ПОДСЧЕТ ЧИСЛА ИМПУЛь- 
;СОВ => СКОРОСТь                          
                                          
CONTR_SPEED                               
        LD BC,#0006                       
        CALL IN_LINE                      
        CALL IN_LINE_D                    
        CALL IN_LINE_D                    
        PUSH BC: POP BC                   
C_SPEED CALL IN_LINE                      
        ADD A,B: LD B,A                   
        DEC C: JR NZ,C_SPEED              
        OR A                              
        RET                               
                                          
LPR> Окончание драйвера чуть ниже.        
                                          
NEXT>> NEXT>>                             
                                          
;ПРИЕМ БЛОКА.                             
;В [B] ЧИСЛО ИМПУЛьСОВ (СКОРОСТь)         
                                          
LOAD_DATA                                 
MOD_BUFF1 EQU $+1: LD HL,0                
        LD A,195 : CP B                   
        JP C,INP_600    ;?>195 = 600      
        LD A,130 : CP B                   
        JP C,INP_1800   ;?>130 = 1800     
        LD A,60 : CP B                    
        CCF : RET C     ;?>060 = 2400     
                                          
INP_FAST LD A,2                           
         LD (SPEED),A ;СКОРОСТь 2400      
        CALL SYNC_FAST: RET C             
        CALL LOAD_BYTE_FAST : RET C       
                                          
;ПРИНИМАЕМ ДЛИНУ БЛОКА: ЕСЛИ 0-Й БАЙТ     
;РАВЕН #08, TO ДЛИНА БЛОКА БОЛьШЕ НА      
;256 БАЙТ                                 
        LD (ZERO_BYTE),A                  
        LD D,0                            
        CP 8: JR NZ,$+3: INC D            
;ПРИНИМАЕМ МЛ. БАЙТ ДЛИНЫ                 
        CALL LOAD_BYTE_FAST: RET C        
        LD E,A: OR A: JR NZ,$+3: INC D    
        LD (BLOCK_LEN),DE                 
                                          
;ПРИНИМАЕМ САМ БЛОК, ДЛИНОЙ [DE]          
                                          
LD_BLOCK_FAST                             
        CALL LOAD_BYTE_FAST: RET C        
        LD (HL),A                         
        INC HL: DEC DE                    
        LD A,D: OR E                      
        JP NZ,LD_BLOCK_FAST               
        RET                               
                                          
;ПРИНИМАЕМ БАЙТ                           
                                          
LOAD_BYTE_FAST                            
        LD B,8   ;ЛОВИМ 8 БИТ             
        CALL IN_LINE                      
                                          
;ОПРЕДЕЛИЛИ ЧАСТОТУ, ЕСЛИ ОНА ЛЕЖИТ       
;В ДИАПАЗОНЕ OT MIN ДО MAX, TO БИТ        
;ПРИНЯТ, ИНАЧЕ - ОШИБКА                   
        CP MIN : JP C,ERR_LDFAST          
        CP MAX : JP NC,ERR_LDFAST         
                                          
;ЕСЛИ ЧАСТОТА БОЛьШЕ ZERO - ПРИНЯЛИ       
;ЕДИНИЦУ, МЕНьШЕ - НУЛь                   
        CP ZERO                           
        RL C ;ПРИНЯЛИ ИНВЕРСНЫЙ БИТ       
        CALL DELAY_47   ;27               
        DEC B: JP Z,_LOAD_BYTE_FAST       
        CALL IN_LINE                      
        JP LOAD_BYTE_FAST+2               
                                          
_LOAD_BYTE_FAST                           
        LD A,C: CPL ;ИНВЕРТИРОВАЛИ БАЙТ   
        PUSH AF                           
        CALL IN_LINE                      
        POP AF                            
        OR A: RET ;БАЙТ ПРИНЯТ            
                                          
ERR_LDFAST        ;ОШИБКА ПРИЕМА          
        POP BC                            
        SCF: RET                          
                                          
;СИНХРОНИЗАЦИЯ БЛОКА                      
                                          
SYNC_FAST PUSH HL                         
        LD DE,MIN*256+ZERO-3              
        LD A,1                            
        LD (SYNC_TABL),A                  
        LD (SYNC_TABL+1),A                
        CALL IN_LINE                      
        CALL DELAY_68                     
         CALL IN_LINE                     
S1_FAST CALL DELAY_57                     
        CALL IN_LINE                      
        CP D : JP C,ERR_SYNC              
        CP E : JP C,S1_FAST               
        LD E,MAX-1                        
        LD HL,SYNC_TABL                   
        CALL DELAY_47                     
        CALL IN_LINE                      
        CALL DELAY_68                     
        CALL DELAY_27                     
         CALL IN_LINE                     
         CALL DELAY_68                    
         CALL DELAY_27                    
        CALL IN_LINE                      
        CALL DELAY_47                     
        CALL DELAY_27                     
        CALL SYNCD1_IN                    
        CALL SYNCD1_IN                    
         LD HL,SYNC_TABL                  
         CALL SYNC2_IN                    
         CALL SYNCD2_IN                   
        LD HL,SYNC_TABL                   
        CALL SYNC1_IN                     
        CALL SYNCD1_IN                    
         LD HL,SYNC_TABL                  
         CALL SYNC2_IN                    
         CALL SYNCD2_IN                   
        LD HL,SYNC_TABL                   
        CALL SYNC1_IN                     
        LD C,A                            
        CALL SYNCD1_IN                    
        CP C : JP M,S2_FAST               
         CALL IN_LINE                     
         CALL DELAY_68                    
         CALL DELAY_27                    
                                          
S2_FAST CALL IN_LINE                      
        CALL DELAY_68                     
        CALL IN_LINE                      
        POP HL                            
        OR A: RET                         
                                          
;!!! ДЛЯ СКОРОСТЕЙ 1800/600 ВСЕ ОЧЕНь     
;ПОХОЖЕ, ПОЭТОМУ БЕЗ КОМЕНТАРИЕВ          
                                          
INP_1800 LD A,1: LD (SPEED),A             
        CALL IN_LINE                      
        CALL DELAY_27                     
        NOP                               
        LD DE,#0E19                       
        LD DE,#0E19                       
        CALL SYNC_1800: RET C             
        LD D,0                            
        CALL LOAD_BYTE_1800: RET C        
        LD (ZERO_BYTE),A                  
        CP 8: JR NZ,$+3: INC D            
;ПРИНИМАЕМ ДЛИНУ                          
        CALL LOAD_BYTE_1800: RET C        
        LD E,A: OR A: JR NZ,$+3: INC D    
        LD (BLOCK_LEN),DE                 
LD_BLOCK_1800                             
        CALL LOAD_BYTE_1800: RET C        
        LD (HL),A                         
        INC HL: DEC DE                    
        LD A,D: OR E                      
        JP NZ,LD_BLOCK_1800               
        RET                               
                                          
LOAD_BYTE_1800                            
         PUSH BC : LD B,8                 
        CALL IN_LINE                      
        CP #0F: JP C,ERR_LD1800           
        CP #2D: JP NC,ERR_LD1800          
        CP #1C: LD A,C: RLA: LD C,A       
        CALL DELAY_27                     
        DEC B: JP NZ,NEXT_B1800           
        LD A,C: CPL                       
        POP BC                            
        PUSH AF                           
        CALL IN_LINE                      
        POP AF                            
        OR A: RET                         
                                          
NEXT_B1800                                
        CALL DELAY_27                     
        NOP                               
        CALL IN_LINE                      
        CALL DELAY_57                     
        CALL DELAY_27                     
        NOP                               
        JP LOAD_BYTE_1800+3               
                                          
ERR_LD1800                                
        POP BC                            
        SCF: RET                          
                                          
SYNC_1800 PUSH HL                         
        PUSH DE                           
        OR A : LD A,1                     
        LD (SYNC_TABL),A                  
        LD (SYNC_TABL+1),A                
        CALL IN_LINE                      
        CALL DELAY_68                     
        CALL DELAY_27                     
        NOP                               
        CALL IN_LINE                      
        CALL DELAY_27                     
        NOP                               
S1_1800 CALL DELAY_68                     
        CALL IN_LINE                      
        NOP                               
        CP D: JP C,ERR_SYNC               
        CP E: JP C,S1_1800                
        LD DE,#0E2E                       
        LD HL,SYNC_TABL                   
        CALL DELAY_47                     
        CALL IN_LINE                      
        CALL DELAY_68                     
        CALL DELAY_27                     
        NOP                               
        CALL IN_LINE                      
        CALL DELAY_68                     
        CALL DELAY_27                     
        NOP                               
        CALL IN_LINE                      
        CALL DELAY_47                     
        CALL DELAY_27                     
        ADD A,0                           
        CALL SYNCD1_IN                    
        CALL SYNCD1_IN                    
        LD HL,SYNC_TABL                   
        CALL SYNC2_IN                     
        CALL SYNCD2_IN                    
        LD HL,SYNC_TABL                   
        CALL SYNC1_IN                     
        CALL SYNCD1_IN                    
        LD HL,SYNC_TABL                   
        CALL SYNC2_IN                     
        CALL SYNCD2_IN                    
        LD HL,SYNC_TABL                   
        CALL SYNC1_IN                     
        LD C,A                            
        ADD A,0                           
        CALL SYNCD1_IN                    
        CP C: JP M,S2_1800                
        CALL IN_LINE                      
        CALL DELAY_68                     
        CALL DELAY_27                     
        NOP                               
S2_1800 CALL IN_LINE                      
        CALL DELAY_68                     
        CALL DELAY_27                     
        NOP                               
        CALL IN_LINE                      
        POP DE                            
        POP HL                            
        OR A: RET                         
                                          
INP_600 XOR A: LD (SPEED),A               
        CALL IN_LINE                      
        NOP                               
        LD DE,#1728                       
        LD DE,#1728                       
        CALL SYNC_600: RET C              
        LD D,0                            
        CALL LOAD_BYTE_600 : RET C        
        LD (ZERO_BYTE),A                  
        CP 8: JR NZ,$+3 : INC D           
;ПРИНИМАЕМ ДЛИНУ                          
        CALL LOAD_BYTE_600 : RET C        
        LD E,A: OR A: JR NZ,$+3: INC D    
                                          
        LD (BLOCK_LEN),DE                 
LD_BLOCK_600                              
        CALL LOAD_BYTE_600: RET C         
        LD (HL),A                         
        INC HL: DEC DE                    
        LD A,D: OR E                      
        JP NZ,LD_BLOCK_600                
        RET                               
                                          
LOAD_BYTE_600                             
                                          
         PUSH DE: PUSH BC                 
         LD B,8                           
        CALL IN_LINE                      
        CALL IN_LINE                      
        CALL IN_LINE                      
        CP #17: JP C,ERR_LDбO0            
        CP #59: JP NC,ERR_LDбO0           
        CP #2D: LD A,E: RLA: LD E,A       
        CALL IN_LINE                      
        DEC B                             
        JP NZ,LOAD_BYTE_600+4             
        LD A,E: CPL: OR A                 
        POP BC                            
        POP DE                            
        RET                               
                                          
ERR_LDбO0 POP BC: POP DE                  
        SCF: RET                          
                                          
SYNC_600 PUSH HL: PUSH DE                 
        OR A                              
        LD A,1                            
        LD (SYNC_TABL),A                  
        LD (SYNC_TABL+1),A                
        LD (SYNC_TABL+2),A                
        LD (SYNC_TABL+3),A                
        CALL IN_LINE                      
        CALL DELAY_68                     
        CALL DELAY_27                     
        NOP                               
        CALL IN_LINE                      
        CALL DELAY_27                     
        NOP                               
S1_600  CALL DELAY_68                     
        CALL IN_LINE                      
        NOP                               
        CP D: JP C,ERR_SYNC               
        CP E: JP C,S1_600                 
        LD A,(SYNC_TABL+4)                
        INC A                             
        LD (SYNC_TABL+4),A                
        ADD A,0                           
        LD DE,#0E59                       
        LD HL,SYNC_TABL                   
        LD D,0                            
        CALL LOAD_BYTE_1800: RET C        
        LD (ZERO_BYTE),A                  
        CALL SYNCD1_IN                    
        CALL SYNCD1_IN                    
        CALL SYNCD1_IN                    
        CALL SYNCD1_IN                    
        LD HL,SYNC_TABL                   
        CALL SYNC2_IN                     
        CALL SYNCD2_IN                    
        CALL SYNCD2_IN                    
        CALL SYNCD2_IN                    
        LD HL,SYNC_TABL                   
        CALL SYNC1_IN                     
        CALL SYNCD1_IN                    
        CALL SYNCD1_IN                    
        CALL SYNCD1_IN                    
        LD HL,SYNC_TABL                   
        CALL SYNC2_IN                     
        CALL SYNCD2_IN                    
        CALL SYNCD2_IN                    
        CALL SYNCD2_IN                    
        LD HL,SYNC_TABL                   
        CALL SYNC1_IN                     
        CALL SYNCD1_IN                    
        CALL SYNCD1_IN                    
        CALL SYNCD1_IN                    
        LD HL,SYNC_TABL                   
        CALL SYNC2_IN                     
        CALL SYNCD2_IN                    
        CALL SYNCD2_IN                    
        CALL SYNCD2_IN                    
        LD HL,SYNC_TABL                   
        CALL SYNC1_IN                     
        CALL SYNCD1_IN                    
        CALL SYNCD1_IN                    
        CALL SYNCD1_IN                    
        LD HL,SYNC_TABL                   
        CALL SYNC2_IN                     
        LD C,A                            
        ADD A,0                           
        CALL SYNC2_IN                     
        CP C : JP M,EXT_SYNC              
        LD C,A                            
        CALL SYNC2_I6                     
        CP C : JP M,EXT_SYNC              
        LD C,A                            
        CALL SYNC2_I6                     
        CP C : JP M,EXT_SYNC              
        OR A : JP Z,ERR_SYNC              
        NOP                               
        CALL IN_LINE                      
EXT_SYNC POP DE: POP HL                   
         OR A: RET                        
                                          
;ПЕРЕДАЧА БЛОКА ИЗ MOD_BUFF,              
;BC - ДЛИНА, A - СКОРОСТь                 
                                          
D_TRANSMIT DI                             
        LD (SPEED),A                      
        PUSH AF  ;СОХРАНИЛИ СКОРОСТь      
MOD_BUFF2 EQU $+1: LD HL,0                
        DEC HL                            
        PUSH HL                           
        ADD HL,BC                         
        EX (SP),HL ;АДРЕС ПОСЛ. БАЙТА     
                                          
        LD (HL),C  ;МЛ. БАЙТ ДЛИНЫ        
                                          
        DEC HL: LD (HL),7                 
        LD A,B: OR A                      
        JR Z,$+3: INC (HL) ;ДЛИНА >256    
                                          
        DEC HL                            
        LD (HL),#AA ;СИНХРО БАЙТ          
        XOR A                             
        DEC HL: LD (HL),A                 
        DEC HL: LD (HL),A                 
        DEC HL                            
                                          
        POP DE  ;АДРЕС ПОСЛЕДНЕГО БАЙТА   
        POP AF  ;СКОРОСТь ПЕРЕДАЧИ        
        OR  A: JP Z,TRANSMIT_600          
        DEC A: JP Z,TRANSMIT_1800         
                                          
TRANSMIT_FAST                             
        XOR  A: LD (HL),A ;СИНХРО         
        DEC HL: LD (HL),A                 
        DEC HL: LD (HL),A                 
        DEC HL: LD (HL),A                 
        DEC HL: LD (HL),A                 
                                          
        CALL LINE_FREE                    
        PUSH BC                           
        LD C,1: CALL DELAY_C              
        POP BC                            
        CALL OUTPUT_FAST                  
        PUSH HL                           
        PUSH DE                           
        LD BC,#020C                       
        LD A,0                            
        NOP: NOP: NOP: NOP                
        JP OUT_BIT2600                    
                                          
;ПЕРЕДАЕМ БЛОК                            
                                          
OUTPUT_FAST                               
        LD A,(HL)         ;ПЕРЕДАЕМ БАЙТ  
        CALL OU_BYTE_FAST                 
        NOP                               
        CALL COMP_HL_DE                   
        RET Z          ;БЛОК ПЕРЕДАН      
        INC HL: JP OUTPUT_FAST            
                                          
;ПЕРЕДАЧА БАЙТА                           
                                          
OU_BYTE_FAST                              
        PUSH HL: PUSH DE                  
        LD BC,#080C                       
OUT_BIT2600                               
        PUSH AF                           
        RLA : JP C,BIT1_FAST              
          LD HL,D0_FAST : JP OB_FAST ;=0  
BIT1_FAST LD HL,D1_FAST : JP OB_FAST ;=1  
                                          
;ПРИ ПЕРЕДАЧИ 1-ГО БИТА MIC OFF МЕНьШЕ НА 
;12 (168 ТАКТОВ),T.К. 168 ТАКТОВ НУЖНЫ    
;ДЛЯ ПОЛУЧЕНИЯ СЛЕД. БАЙТА,КОНТРОЛЯ,...   
                                          
OB_FAST RRA                               
        LD A,(HL)                         
        SUB C : LD D,A : INC HL           
        LD E,(HL) : INC HL                
        CALL OUT_DATA                     
        POP AF                            
        RLCA                              
        DEC B                             
        LD C,0 : LD C,0 : NOP             
        JP NZ,OUT_BIT2600                 
        POP DE : POP HL                   
        RET                               
                                          
;ДЛЯ 1800/600 ПОХОЖЕ                      
                                          
TRANSMIT_1800                             
        XOR  A : LD (HL),A                
        DEC HL : LD (HL),A                
                                          
        CALL LINE_FREE                    
        PUSH BC                           
        LD C,1 : CALL DELAY_C             
        POP BC                            
        CALL OUTPUT_1800                  
        PUSH HL : PUSH DE                 
        LD BC,#020C                       
        LD A,0                            
        NOP : NOP : NOP : NOP             
        JP OUT_BIT1800                    
                                          
OUTPUT_1800                               
        LD A,(HL)                         
        CALL OU_BYTE_1800                 
        NOP                               
        CALL COMP_HL_DE                   
        RET Z                             
        INC HL: JP OUTPUT_1800            
                                          
OU_BYTE_1800                              
        PUSH HL: PUSH DE                  
        LD BC,#080C                       
OUT_BIT1800                               
        PUSH AF                           
        RLA: JP C,BIT1_1800               
          LD HL,D0_1800: JP OB_1800 ;=0   
BIT1_1800 LD HL,D1_1800: JP OB_1800 ;=1   
                                          
OB_1800 RRA                               
        LD A,(HL)                         
        SUB C: LD D,A: INC HL             
        LD E,(HL): INC HL                 
        CALL OUT_DATA                     
        POP AF                            
        RLCA                              
        DEC B                             
        LD C,0: LD C,0: NOP               
        JP NZ,OUT_BIT1800                 
        POP DE: POP HL                    
        RET                               
                                          
TRANSMIT_600                              
        CALL LINE_FREE                    
        PUSH BC                           
        LD C,1: CALL DELAY_C              
        POP BC                            
        CALL OUTPUT_600                   
        PUSH HL: PUSH DE                  
        LD BC,#020D                       
        LD A,0                            
        NOP: NOP: NOP: NOP                
        JP OUT_BITбO0                     
                                          
OUTPUT_600                                
        LD A,(HL)                         
        CALL OU_BYTE_600                  
        RLA: LD B,A                       
        CALL COMP_HL_DE                   
        LD A,B: RRA                       
        RET Z                             
        INC HL: JP OUTPUT_600             
                                          
OU_BYTE_600                               
        PUSH HL: PUSH DE                  
        LD BC,#080D                       
        NOP                               
                                          
OUT_BITбO0                                
        PUSH AF                           
        RLA: JP C,B71_600 ;B7=1           
        RRA: JP C,B70_B01 ;B7=0,B0 =1     
        LD HL,D00_600 ;B7 =0 B0 =0        
        JP OB_600                         
                                          
B71_600 RRA: JP NC,B71_B01                
                                          
        LD HL,D10_600   ;B7=1 B0=0        
        JP OB_600                         
                                          
B71_B01 LD HL,D11_600   ;B7=1 B0=1        
        JP OB_600                         
                                          
B70_B01 LD HL,D01_600   ;B7=0 B0=1        
        JP OB_600                         
                                          
OB_600  NOP                               
        LD A,(HL)                         
        SUB C: LD D,A: INC HL             
        LD  E,(HL): INC HL                
        CALL OUT_DATA                     
        CALL OUT_DATA                     
        POP AF                            
        RLCA                              
        DEC B                             
        LD C,0: NOP : NOP                 
        JP NZ,OUT_BITбO0                  
        POP DE:  POP HL                   
        RET                               
                                          
;СРАВНИТь HL И DE                         
COMP_HL_DE                                
        NOP                               
        LD A,H : CP D                     
        JP NZ,$+6: LD A,L: CP E: RET      
        NOP: NOP: RET                     
                                          
;ПЕРЕДАЧА БИТА                            
OUT_DATA                                  
        DEC D: JP NZ,$-1 ;ЗАДЕРЖКА D      
                                          
BORDER_0 LD A,#00   ;MIC OFF              
        JP $+3                            
        OUT (#FE),A                       
        DEC E: JP NZ,$-1 ;ЗАДЕРЖКА E      
                                          
BORDER_1 LD A,#08   ;MIC ON               
         JP $+3                           
         OUT (#FE),A                      
        LD D,(HL): INC HL                 
        LD E,(HL): INC HL                 
        NOP                               
        RET                               
                                          
;ТАБЛИЦЫ ДЛЯ ПЕРЕДАТЧИКА                  
                                          
;1800                                     
D0_1800 DB 36,36+13 ;ЧАСТОТЫ ДЛЯ "0"      
D1_1800 DB 67,67+13 ;ЧАСТОТЫ ДЛЯ "1"      
                                          
D00_600 DB #36,#44,#40,#44 ;B7 =0 B0 =0   
D01_600 DB #57,#58,#49,#44 ;B7 =0 B0 =1   
D10_600 DB #57,#65,#61,#65 ;B7 =1 B0 =0   
D11_600 DB #36,#4D,#54,#65 ;B7 =1 B0 =1   
                                          
D0_FAST DB 28,28+13  ;КОДА ПЕРЕДАЧИ "0"   
D1_FAST DB 51,51+13  ;SPEED FAST    "1"   
                                          
MIN     EQU 11                            
MAX     EQU 37                            
ZERO    EQU 23                            
                                          
;ЧИСЛО ТАКТОВ В ПЕРЕДАЧИ БИТА             
;T=(2*D+13)*14+56  D - ЧИСЛО ИЗ ТАБЛИЦЫ   
;D0_?? ДЛЯ ПЕРЕДАЧИ "0" И D1_?? ДЛЯ "1"   
                                          
;СРЕДНЯЯ СКОРОСТь :                       
;SPEED=(SPDO+SPD1)/2                      
;SPDO=3500000/T0  SPD1=3500000/T1         
                                          
;ПРИЕМНИК :                               
;ЕСЛИ C ЛИНИИ ПРИНЯТО ЧИСЛО < MIN -ОШИБКА 
;ЕСЛИ > MAX : ОШИБКА                      
;ЕСЛИ MIN < ?? < ZERO : ПРИНЯЛИ "0"       
;ЕСЛИ ZERO < ?? < MAX : ПРИНЯЛИ "1"       
                                          
;ZERO=T0/46                               
;MAX=T1/46                                
;MIN=ZERO-11..13                          
                                          
;В ДАННОМ ДРАЙВЕРЕ П/П РАБОТЫ C ЧАСАМИ    
;ОТСУТСТВУЮТ, И СТОЯТ "ЗАГЛУШКИ"          
                                          
;УСТАНОВИТь ВРЕМЯ [A]-[B]-[C]             
                                          
D_SET_TIME                                
                                          
;СЧИТАТь ВРЕМЯ [A]-[B]-[C]                
                                          
D_RD_TIME                                 
                                          
;ЕСЛИ ЧАСЫ ПОЛУАВТОНОМНЫ, TO ЭТА П/П      
;ПРОИЗВОДИТ ПОДСЧЕТ ВРЕМЕНИ               
                                          
D_CAL_TIM                                 
                                          
;УСТАНОВИТь ТАЙМЕР НА [BC] МИНУТ          
                                          
D_SET_ALR                                 
                                          
;ДОБАВИТь К ТАЙМЕРУ [BC] МИНУТ            
                                          
D_ADD_ALR                                 
         SCF: RET                         
                                          
;ЕСЛИ ВРЕМЯ ИСТЕКЛО, CY=1                 
                                          
D_RD_ALR XOR A: RET                       
                                          
END                                       
                                          
                                          



Другие статьи номера:

От редакции - Cвои статьи, вопросы, предложения и т.д. присылайте в виде файла.

Новости - Оказывается CDOS-device может эмулировать Sound Drive.

Новелла - Новелла к игре Lord of Chaos (часть 1-4).

Программирование - Драйвер CDOS-модема.

Личность - Первый принцип Гарвея Гаррисона (часть 2).

График BBS - График работы BBS на неделю.


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Part 6 - Hacking guide.
От редакции - о переделках в газете.
Scene - Emotional consumerism .
Editorial - alff: Changes... is air...
Презент - описание Real Commander v1.4.

В этот день...   21 ноября