┌----------------------------------------┐ │░░░░░░░░░░ Драйвер 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