┌---------------------------------------┐ │░░░░░░░░░░ CDOS modem driver ░░░░░░░░░│ └---------------------------------------┘ LPR>In the sixth issueZX-FORMAT, was published the vicom modem driver is forged, it is different from CDOS only in bits. But the most interesting thing what about ~throwing~ this driver onto disk? impossible, but copying 30 kB onto paper the text is also unrealistic. Then online the first call appeared to ~rip out~ this driver believe and behold, what you see is the fruit symbiosis of A. Nikiforov and Stalker Debugger :). ~Discard~ this and next sections to disk, load into ZX-ASM, delete everything superfluous, Import and finally assemble. ------------------------------ D R A Y V E R ------------------------ ; Attention! ; In the program Macro Modem v2.20 functions ;works with clock/timer are not used, ;they are reserved for future versions.CALLING EQU 01 ;DIALING PERMISSION FLAG ;IF "1", THEN THE DRIVER WILL DIAL ;HOMEP AND RESPOND TO CALLS ;IF "0" - HE WILL BE, HO AND HE WILL BE ;HOST IN THE ABSENCE OF "GADDY" ORG #C000 ;SUBROUTINE KERNAL 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_ALRJP D_RD_ALR ;DRIVER WORKING VARIABLES LINE_STATUS DB 0 SPEED DB 0 LCOUNT_A DB 0 LCOUNT_B DB 0 LCOUNT_C DB 0 ZERO_BYTE DB 0 ;BYTE COMING BEFORE ;BLOCK LENGTH SYNC_TABL DS 15 ;INSTALLING THE DRIVER ;in: [HL] MODEM BUFFER ADDRESS ;out: IN BUFFER IN ASCII VALUE FORM ;SPEED. ;FOR EACH SPEED 4 BYTES, ;NUMBER OF SPEEDS 8, ENDS WITH #00 D_INSTAL RET C ;IF THE DRIVER IS CALLED WITH INSTALLED ;FLAG CY - TO THIS IS RUN FOR ;UNPACKING AND IGNORE IT LD (MOD_BUFF1),HL ;WRITTEN IN LD (MOD_BUFF2),HL ;REQUIRED PLACES LD (MOD_BUFFЗ),HL ;ADDRESS LD (MOD_BUFF),HL ;BUFFER ;TRANSFER TODRIVER SPEED BUFFER 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 ;READ DRIVER INFORMATION ;out: BY [DE] THE NAME IS RECORDED ;DRIVERS (UP TO 80 CHARACTERS), ;ENDS WITH CODE #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 ;READ LINE/DRIVER STATUS ;in: [A] CURB COLOR ;out: [A] - DATA FOR PORT#FE ; T.K. CURB COLOR + CONTROL BITS ; LINE AND LINE OUT ;[B]: BY BITS: ; 0 LINE STATUS (Idle/Busy) ; 3 presence of tone dialing ; 4 TURN OFF TURBO WHEN CALLING DRIVER ; 5 LINE CONTROL ; 6 PRESENCE OF TIMER ; 7 AVAILABILITY OF WATCHES 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 ;TURN OFF TURBO, ECTb LINE CONTROL, ;HET CLOCK, TIMER OR %00110000 ELSE ;TURN OFF TURBO, HET LINE CONTROL, ;HET CLOCK, TIMER, HANDBOOK OFFOR %00010001 ENDIF LD B,A POP AF: RET ;PICK UP D_ON_LINE LD A,#20: JR ON_OFF_L ;Hang up D_OFF_LINE XOR A ON_OFF_L ;CHANGE LINE STATUS IF HET ;LINE CONTROL - IMMEDIATE RETURN 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 ;DIAL HOMEP, HANDBOOK IS ALREADY PICKED UP ; in: ; [HL] - BUFFER ADDRESS C HOMEPOM ; [A] - 0pulse, 1 tone ; [B] pulse period ms, std. 100 ; [C] interdigit pause ms/10 ; CY=1 ERROR, ERROR CODE IN [A]: ; 0 DIALING ERROR ; 1 NO LONG BEEP ; 2 INTERRUPT ; CY=0 CONNECTION ESTABLISHED: ;DATA IS RETURNED AS FROM SET_CON_P D_CALL IF CALLING LD (ID_CALL+1),HL PUSH BC ;SETTING P/P LINE SCAN XOR A: CALL D_WAIT_INS POP B.C. LD A,C: LD (CDEL_COD+1),A ;PULSE PERIOD IS SET, ACCORDING TO STANDARD ;GIVEN 2/5 PERIOD THE LINE IS CLOSED, ;AND 3/5 PERIOD THE LINE IS OPEN ;DIVIDE THE PERIOD BY 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 PERIOD LD(CDEL_1+1),AADD A,B ;3/5 PERIOD LD(CDEL_0+1),A ;RECORDING THE VALUES OUTPUT TO THE PORT ;#FE TO CLOSE/OPEN THE LINE LD A,(BORDER_0+1): AND #0F LD(DCAL_OFF+1),A LD A,(BORDER_1+1): OR #20 LD(DCAL_ON+1),A ;SMALL PAUSE BEFORE STYLING EI: LD B.45: HALT: DJNZ $-1 ;LONG BEEP CONTROL: ;MAKE 200 LINE POLLS IF ;HEAR THE BEEZ 30 TIMES IN A ROW - EVERYTHING IS OK LD BC,200*256+30 WAIT_DIA CALL WAIT_CALL JR C,DWAIT_R ;BEEP HET DEC C JR Z,ID_CALL ;CAUGHT 30 TIMES JR DWAIT_N ;IF YOU HAVE LOST THE BEEP ONCE - SET- ;Reset the counter to 30 DWAIT_R LD C,30 ;IF SPACE IS PRESSED -EXIT DWAIT_N LD A,#7F: IN A,(#FE) RRCA: JR NC,BRK_CALL DJNZ WAIT_DIA NO_DIAL LD A,1: SCF: RET ;HET SIGNAL BRK_CALL LD A,2: SCF: RET ;INTERRUPT ERRD_CALL XOR A: SCF: RET ;ERROR ED_CALL XOR A: RET ;HOMEP DIALED ;DIALING THE NUMBER ID_CALL LD HL,0 ;HERE WILL BE THE BUFFER ADDRESS LD A,(HL): INC HL LD (ID_CALL+1),HL OR A ;FINDING CODE #00 JR Z,ED_CALL ;FINISH DIALING ;SYMBOLS "-", "(", ")", " " IGNORE 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 ;IF THIS IS NOT A DIGIT - DIALING ERROR ;THE DIGIT "0" CORRESPONDS TO 10 PULSE JR NZ,$+4: LD A,10 CP 11: JR NC,ERRD_CALL LD B,A ;DIAL A NUMBER IN [B] QUANTITYIMPULSOV CALL_C ;BREAK OF LINE ON bOms (3/5) DCAL_OFF LD A,0 AUGUST (#FACT),A CDEL_0 LD A,0 DDEL_0 LD C,248 DEC C: JP NZ,$-1 DEC A: JP NZ,DDEL_0 ;LINE CLOSING AND PAUSE CHOms (2/5) DCAL_ON LD A,0 AUGUST (#FACT),A ;DELAY BY [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 ;INTERDIGITAL PAUSE IN 6OOms CDEL_COD LD B,0 W_CDEL NOP: NOP: LD DE,1457DEC DE:LD A,D OR E: JP NZ,$-3 DJNZ W_CDEL ;IF SPACE IS PRESSED - EXIT, ELSE DIAL ;HOMEP NEXT LD A,#7F: IN A,(#FE) RRCA: JR NC,BRK_CALL JR ID_CALL ;POLLING THE LINE 32 TIMES 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 B.C. ;BEEP CONTROL, MEDIUM. ARIFMS. ;FREQUENCY VALUE FOR 32 SURVEYS 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 ;INTERVAL 150...250 - BEEP FREQUENCY CP 150: RET C CP 250: CCFRET ELSE XOR A: SCF: RET ENDIF ;CALLED WHEN A CALL IS DETECTED. ;THE TUBE IS REMOVED. + NUMBER IDENTIFICATION ;(MISSING HERE!) ;out: MOD_BUFF NUMBER IN ASCII, ENDING WITH 0 D_AON CALL D_ON_LINE LD B,75: EI: HALT: DJNZ $-2: DI ;AFTER REMOVING THE TUBE, PAUSE IS 1.5 SEC. ;IF ECTb Caller ID, TO OH CAN DETERMINE ;HOMEP ; TRANSFER THE MESSAGE TO THE MODEM BUFFER ;O REMOVING THE TUBE MOD_BUFFЗ EQU $+1: LD DE,#1111 LD HL,AON_TXT LD BC,EAON_TXT-AON_TXT LDIR RET AON_TXT DB 13,"Modem connected to line", 13.0 EAON_TXT;THE FOLLOWING TWO P/P ARE USED ;AS "STUBS", T.K. AUTO SELECTION ALGORITHM ;SPEED NOT YET CONSIDERED ;establish connection, transfer ;T.E. FIRST "TRANSMITTING", THEN "LISTENS" SET_CON_A ;establish connection, receive ;T.E. FIRST "LISTENS", THEN "TRANSMITT" 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 ;ESTABLISHING CONNECTION ;IN MOD_BUFF THE TEXT MESSAGE IS RETURNED. ;O CONNECTION, AT THE END - CODE #00 ;B [A] SET SPEED OR #80 ;IF IT IS UNDEFINED LD HL,CARR_TXT LD BC,ECARR_TXT-CARR_TXT LDIR LD A,#80 ;SPEEDUNDEFINED RET CARR_TXT DB 13,"Connection established", 13.0 ECARR_TXT ;INSTALLATION BEFORE LINE SCAN ;B [A] - LINE SOUND OUTPUT VOLUME ;VIA 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 ;SCAN LINE ;out ;CY=1: NOTHING ; [B] NUMBER OF POLLING CYCLES ; [C] HOW MANY CYCLES SHOULD THERE BE? ;CY=0, ;[A] - CODE:;1 - BLOCK RECEIVED, 2 - BUSY, 3 - CALL D_WAIT_LN D.I. 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 ;POLLING THE LINE TO THE BLOCK CLOCKING SIGNAL AND ;CONTROL OF BEEPS, FIRST ;COUNT THE AVERAGE. ARIFMS. FREQUENCY VALUE ;FOR 16 SURVEYS MDLOOP1 IN A,(#FE): AND #20 ;ANALYSIS/HET CALL SIGNAL 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 ;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 LSRA H: RR L : SRA H: RR L LD A,L: SRA A ;IN THE INTERVAL 150...250 - BEEP FREQUENCY ;IF BEEP, TO A=1 ELSE A=0 CP 150: JR C,TST_OFFL CP 250: JR C,TST_ONL TST_OFFL XOR A: JR $+4 TST_ONL LD A,1 ;IF COCT. SIGNAL HE CHANGED, TO ;JUST INCREASE THE COUNTER. IF ;CHANGED TO SWITCH THE COUNTER 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 ;FREQUENCY CHANGED: NEW_DTL DEC A: JR Z,NEW_DTL1 ;BECAME "0": SWITCHING THE COUNTER LD HL,COUNTO+1 : LD (HL),0 LD (ADR_IDL+1),HL ;IF THERE WERE >4 ONES AND >4 ZEROS IN A row,;MEANS YOU HAVE CAUGHT A CLEAR SIGNAL COUNT1 LD A,0: CP 4: JP C,RES_OFF LASTO LD A,0: CP 4: JP C,RES_OFF ;HAVING 3 BEEPS, IT WILL TURN OFF OFFCOU LD A,0: INC A: LD (OFFCOU+1),A CP 3: JR Z,BUSY_FOUND ;FREQUENCY BECAME "1": SWITCHING THE COUNTER 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 "BUSY" RET ;CAUGHT A CALL, REALITY CHECK ;IF THE CALL SIGNAL STAYS ON ;SOME TIME IS A CHALLENGE IN NATURE RING LD C,2RING1 LD B,30: NOP: DJNZ $-1 IN A,(#FE): AND #20 JP NZ,D_WAIT_LN DEC C: JR NZ,RING1 ;CALL ECTb, WE WAIT FOR ITS END RING2 IN A,(#FE): AND #20: JR Z,RING2 LD A,3 ;CY=0, A=3 "CALL" RET E_WAIT_LN LD BC,#0101 SCF: RET ;CY=1 - NOTHING HET ;INPUT POLLING: IN [A] WILL BE SIGNAL FREQUENCY 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),ALD A,E POP DE: POP HL RET END_TIN_F DEC E: JR RET_TIN_F ;HAVE CAUGHT A SYNCHRO SIGNAL, ACCEPT A BLOCK 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 SUCCESSFULLY RECEIVED BLOCK OR A: LD A,1 RET ;LONG WAITING FOR BLOCK AND ACCEPTING BLOCK ;out: CY HET BLOCK ;[BC] LENGTH ;[D] SPEED (#80 UNDEFINED) D_WAIT_BLC CALL WAIT_LINE: RET C CALL LOAD_DATA CALL LINE_FREE JR E_LOAD_DTSCAN_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 CALLIN_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 : LDL,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 BCC_SPEED CALL IN_LINE ADD A,B: LD B,A DEC C: JR NZ,C_SPEED OR A RET LPR> The end of the driver is just below. NEXT>> NEXT>> ;RECEIVING BLOCK. ;B [B] NUMBER OF PULSE (SPEED) 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 ;SPEED 2400 CALL SYNC_FAST: RET C CALL LOAD_BYTE_FAST : RET C ; ACCEPT BLOCK LENGTH: IF 0TH BYTE;EQUAL TO #08, THEN THE LENGTH OF THE BLOCK IS LONGER BY ;256 BYTES LD(ZERO_BYTE),A LD D,0 CP 8: JR NZ,$+3: INC D ; WE ACCEPT ML. BYTE LENGTH CALL LOAD_BYTE_FAST: RET C LD E,A: OR A: JR NZ,$+3: INC D LD(BLOCK_LEN),DE ;ACCEPT THE BLOCK ITSELF, LENGTH [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 ;RECEIVE BYTE LOAD_BYTE_FAST LD B,8 ; CATCH 8 BIT CALL IN_LINE ;DETERMINED THE FREQUENCY IF IT IS LIE ;IN THE RANGE FROM MIN TO MAX, TO BIT ;ACCEPTED, ELSE - ERROR CP MIN : JP C,ERR_LDFAST CP MAX : JP NC,ERR_LDFAST;IF THE FREQUENCY IS GREATER THAN ZERO - ACCEPTED ;ONE, LESS THAN ZERO CP ZERO RL C ;RECEIVED INVERSION BIT 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 ;BYTE INVERTED PUSH AF CALL IN_LINE POP AF OR A: RET ;BYTE RECEIVED ERR_LDFAST ;RECEIVE ERROR POP B.C. SCF: RET ;BLOCK SYNCHRONIZATION 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_57CALL 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 ;!!! FOR SPEED 1800/600 EVERYTHING IS VERY ;LIKE SO NO COMMENTS 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 ;ACCEPT LENGTH 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бO0CP #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 ;SAVE SPEED MOD_BUFF2 EQU $+1: LD HL,0 DEC HL PUSH HL ADD HL,BC EX (SP),HL ;SEQ ADDRESS BYTE LD (HL),C ;ML. BYTE LENGTH DEC HL: LD (HL),7 LD A,B:OR A JR Z,$+3: INC (HL) ;LENGTH >256 DEC HL LD (HL),#AA ;SYNCHRO BYTE XOR A DEC HL: LD (HL),A DEC HL: LD (HL),A DEC HL POP DE ;ADDRESS OF LAST BYTE POP AF ;BAD RATE OR A: JP Z,TRANSMIT_600 DEC A: JP Z,TRANSMIT_1800 TRANSMIT_FAST XOR A: LD (HL),A ;SYNCHRO DEC HL: LD (HL),A DEC HL: LD (HL),ADEC 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 AFRLA : JP C,BIT1_FAST LD HL,D0_FAST : JP OB_FAST ;=0 BIT1_FAST LD HL,D1_FAST : JP OB_FAST ;=1 ;WHEN TRANSMISSING THE 1ST BITT, MIC OFF IS LESS BY ;12 (168 BLOCKS),T.K. 168 BARKS NEEDED ;TO OBTAIN THE NEXT. BYTE, CONTROL,... 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 ;FOR 1800/600 IT'S SIMILAR TRANSMIT_1800 XOR A : LD (HL),A DEC HL : LD (HL),A CALL LINE_FREE PUSH BC LD C,1 : CALL DELAY_C POP B.C. 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 NOPOUT_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: NO : NO JP NZ,OUT_BITбO0 POP DAY: POP HL RET;COMPARATE HL AND DE COMP_HL_DE NOP LD A,H : CP D JP NZ,$+6: LD A,L: CP E: RET NOP: NOP: RET ;TRANSFER BIT OUT_DATA DEC D: JP NZ,$-1 ;DELAY D BORDER_0 LD A,#00 ;MIC OFF JP$+3 OUT(#FE),A DEC E: JP NZ,$-1 ;DELAY 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 ;TABLES FOR TRANSMITTER ;1800 D0_1800 DB 36.36+13 ;FREQUENCIES FOR "0" D1_1800 DB 67.67+13 ;FREQUENCIES FOR "1" D00_600 DB #36,#44,#40,#44 ;B7 =0 B0 =0D01_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 ; TRANSMISSION CODE "0" D1_FAST DB 51,51+13 ;SPEED FAST "1" MIN EQU 11 MAX EQU 37 ZERO EQU 23 ;NUMBER OF CLOCKS IN BIT TRANSMISSION ;T=(2*D+13)*14+56 D - NUMBER FROM THE TABLE ;D0_?? FOR TRANSMISSION "0" AND D1_?? FOR "1" ;AVERAGE SPEED: ;SPEED=(SPDO+SPD1)/2 ;SPDO=3500000/T0 SPD1=3500000/T1 ;RECEIVER: ;IF A NUMBER < MIN IS RECEIVED FROM THE LINE - ERROR ;IF > MAX : ERROR ;IF MIN < ?? < ZERO : ACCEPTED "0" ;IF ZERO < ?? < MAX : ACCEPTED "1" ;ZERO=T0/46 ;MAX=T1/46 ;MIN=ZERO-11..13 ;THIS DRIVER HAS WORKING WITH THE CLOCK ;THEY ARE MISSING, AND THERE ARE "PLUGS";SET TIME [A]-[B]-[C] D_SET_TIME ;COUNT TIME [A]-[B]-[C] D_RD_TIME ;IF THE WATCH IS SEMI-AUTONOMOUS, THEN THIS P/P ;CALCULATES TIME D_CAL_TIM ;SET TIMER TO [BC] MINUTES D_SET_ALR ;ADD TO TIMER [BC] MINUTES D_ADD_ALR SCF: RET ;IF TIME IS UP, CY=1 D_RD_ALR XOR A: RET END
Share your thoughts about the article