ZX Format #06
29 июля 1997 |
|
Programmers - MMD - the driver. Description of the structure of the modem driver for the terminal program MMD.
The structure of the modem driver for the program MMD 2.20 music by DNK (C) MAS _______________________________ To work terminalki "Macro Modem v2.20 "requires a modem. This driver performs all functions reception / transfer information and handles the telephone line and system hours. Driver to be on the 6 th page 49,152 addresses (# C000). Under his needs allocated all 16Kb given page. Log in driver is done through an entry point, located in the very early drivers ie from address 49152. Attention! DRAYVER_NE_DOLZHEN: - Spoil registers content IX, IY, SP; - Change any of the memory cell core program except for those specifically allocated buffer for the exchange of information; - Change the mode interrupt (interrupt status can be changed - all the same it will be prohibited). Driver entry points: INSTALLING DRIVERS D_INSTAL EQU # C000 If you call in a couple regitrovoy [HL] will be the address of the working buffer for the transmit / receive data. This buffer located in main memory, and has a size of about 270 bytes up, and about 30 down from the specified value. Exchange data between main program and the driver made only through the clipboard. With installations in the buffer driver should be written in the form of ASCII value existing rates. On each speed allocated 5 bytes, total velocities - 8. Should describe each speed, if the driver supports a smaller number, then the descriptors are filled with non-existent velocity Code # 00. Example descriptor velocities: DEFB "600", 1 st speed 600 baud DEFB "1800", 2 nd speeds of 1800 baud DEFB "2400", the third at 2400 baud DEFS 25; only 3 speed, ; Remaining 5 absent The program takes into account the fact that the driver modem can be packed. Therefore, the installation procedure is called twice. Ie the first call to unpacking driver, and the second of its installation. The program uses the jars for transport Facebook to inform driver what challenge occurs: - If carry flag is set - the first call - If carry flag is cleared - the second. OBTAINING INFORMATION ABOUT THE DRIVERS D_COPYREQU # C003 This feature puts in the work buffer driver information. This information is the driver name and the name its author. Buffer Size - 50 bytes line should end with a code # 00 Example of a function D_COPYR: LD DE, (WORK_ADR); buffer address LD HL, TEXT; address line LD BC, ETEXT-TEXT; length of the string LDIR; moved and RET; returned TEXTDEFB "Vicomm-driver v2.95" DEFB "(C) 1997 * MAS *" DEFB 0 ETEXT READING THE STATUS LINE / DRIVER D_RD_STAT EQU # C006 This function returns the DRIVERS line and also produces Cor Correction of data for the port # FE. When invoked given function in [A] located current color curb. On return from the function: - √ In case [B] various bits is characterized by: bit0 - the status line: "1" modem is connected to the line, "0" is disabled bit1 bit2 , Bit3 if "1" then driver may recruit Room tone method. bit4 if "1" - to disable TUR BO-mode when you call the driver (for all modems except XTR - required) bit5 if "1", the driver allows you to pack ravlyat line (to connect the modem to line and disable) - Bit6 if "1" then the driver has hours - Bit7 if "1", then the driver has a tie measures √ In the case [A] will be located data port # FE. If the driver for his needs is not using port # FE, then the contents of the battery should not be changed. For example: Vicomm with gadgets "v1.2 transmits data and controls the line via port # FE, and when you call this function to install 3 rd and 5 th bits of the battery in accordance with their needs. INSTALLATION OF FRONT LINE POLLS D_WAIT_INS EQU # C009 This function is called immediately before the loop function calls the survey line. If the driver must set any variables, this function and it does. When you call this function, the battery will be a number from 0 to 15, characterizes the volume with which the functions of the survey lines should sound output through the embedded speaker. Vydor device for sound output is not negotiated (you can use beeper, AY, COVOX, etc.) When sound on AY There is one restriction: if the sound output not necessary, ie [A] = # 00, then change the contents of the registers muzprotsessora not recommended. SURVEY LINE D_WAIT_LN EQU # C00C This function produces a survey line within a short period of time. This function returns Output: √ If the carry flag is set, then nothing happened, while the register [B] indicates the number of produced Polls line, and in case [C] - how much vsogo be polls. The data in the registers [B] and [C] can more or less rhythmically blinking cursor and query keyboard. For example, if the function performs 15 polls the line, and the presence of noise in line in any of the cycles of the survey returns. In the case [B] indicates as function of time to perform surveys. If the function of the survey line runs always strictly fixing the time, then register [B] is entered # 01 Contents of the register [C] allows you to adjust chastoru Mugan cursor keys and the survey. The higher the number, the rarer and rhythmically blinks cursor. √ If the function returns D_WAIT_LN carry flag is cleared, then there was some event. In case [A] is indicated by its code: # 01: was adopted by the unit. Adopted by the unit is in the buffer on the modem and its length in register pair [BC] The Register [D] is the speed at which it was submitted this block. If the speed does not determine succeeded then [D] recorded # 80 # 02: were discovered short hooters # 03: it was discovered the call (call) LONG WAITING D_WAIT_BLC EQU # C00F This function produces long poll line approximately 1 ... 4 seconds. When function return: √ If carry flag installed then nothing was accepted , √ If the carry flag is cleared, then took block: Adopted by the unit is in the buffer on the modem and its length in the register pair [BC] B register [D] located speed at which was handed given block. If the speed could not be determined, then [D] entered # 80 DATA TRANSFER D_TRANSMIT EQU # C012 This function sends the data block. The data itself is in the buffer modem in register pair [BC] is the length of the transmission unit, in the [A] - speed. Connect the modem to the line D_ON_LINE EQU # C015 RETIRE FROM LINE MODEM D_OFF_LINE EQU # C018 These functions are just "remove" or "Lay" handset. The function did not spread and the functions do not return. SEND NUMBER D_CALL EQU # C01B This function performs a set of numbers. If you call the modem is already connected to the line and register pair [HL] buffer address is the phone number that you must dial. Number represents the ASCII string that ends with code # 00. If a line meets a symbol "-", then set it to skip. During the recruitment is necessary to analyze pressing the keys, and when it is pressed to produce vyod from the function. Also, when entering a function: √ in the register [A] a method set Prefix: "0" - Pulse, "1" - tone. , √ in the register [B] specified pulse period in ms - √ in case [C] mezhtsifrovaya pause ms/10 This function returns: √ Carry Flag cleared - a set of numbers performed successfully. √ Carry Flag is set - bug error code [A]: # 00 ERROR SET # 01 No long Toots # 02 execution is terminated, pressed the spacebar> This function is called If you notice BELL. Modem connects to the line and Specifies the number. D_AON EQU # C01E When you call the function: [A] number zaprovoe [B] pause before requesting [C] the number of digits [D] sensitivity to the response PBX [E] the sensitivity of the line When leaving the functions in the modem buffer be ASCII string with a message ending with Code # 00. Pairing ACTIVE SET_CON_A EQU # C021 The passive SET_CON_P EQU # C024 These functions try to choose nailudshuyu exchange rate. Function active Setup passes at different speeds data, and then check how they started. Function of the passive installation first accepts data then informs their admission. Konkternaya implementation of these functions not specified. Both functions return a text message about the speed required one. Message located in the buffer ends with a modem and Code # 00. Also at return from functions accumulator written number required one speed or # 80 if speed select failed. In case of impossibility of performance function returns with carry flag set. SET TIME D_SET_TIME EQU # C027 This feature allows you to set current time. If you call the data located in registers [A], [B], [C]: [A] - Watch, [B] - minute, [C] - seconds. Data presented in BCD form. In the case of error, the function returns carry flag set. COUNT TIME D_RD_TIME EQU # C02A This feature allows you to see the current time. On return from the function data should be kept in registers [A], [B], [C] in BCD form. In [A] - hours, [B] - minute, [C] - seconds. In the case of error, the function returns with carry flag set. CORRECTION TIME D_CALC_TIM EQU # C02D This function is called multiple times per minute. If the clock is not used are completely independent (eg Hours are femtosecond counter pulses connected to parallel port), and it takes time correction, then it uses this function. Attention! This function must preserves the value of all registers! Set the timer D_SET_ALR EQU # C036 If the driver supports the timer mode, this function should set timer indications in register pair [BC] seconds. In the case of error, the function returns carry flag set. ADD TO TIMER D_ADD_ALR EQU # C039 This feature adds to the remaining time indication in the register pair [BC] seconds. In the case of error, the function returns carry flag set. Time has run out? D_RD_ALR EQU # C03C This function verifies approached-whether to the end of the time set in timer. If time out, then the function returns with carry flag set. Attention! The program Macro Modem v2.20 features works with clock / timer not used they are reserved for buduyuschie version. _____ We offer you an example drivers under the most simple "modem" common in Saint-Petersburg. CALLING EQU 01 ; FLAG PERMISSION DIALING And if "1", then the drivers will gain ; NUMBER AND RESPOND TO CALLS And if "0" - WILL NOT, BUT WILL NOT ; Hangs ABSENCE gadgets ORG # C000 ; KERNAL SUBPROGRAMME 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 ; Working variables DRIVERS LINE_STATUS DB 0 SPEED DB 0 LCOUNT_ADB 0 LCOUNT_BDB 0 LCOUNT_CDB 0 ZERO_BYTE DB 0; BYTES are before ; LENGTH IN BLOCK SYNC_TABL DS 15 ; INSTALLING DRIVERS ; In: [HL] Address of buffer MODEM ; Out: the buffer in ASCII form of values , Speed. ; Every SPEED 4 bytes, ; Number of speeds, 8 ENDS # 00 D_INSTAL RET C And if DRAVER Called SET ; FLAG CY - it's RUNNING FOR , Unpacking, and ignore it LD (MOD_BUFF1), HL; Write to LD (MOD_BUFF2), HL; THE RIGHT PLACE LD (MOD_BUFF3), HL; ADDRESS LD (MOD_BUFF4), HL; BUFFER ; Throws in BUFFER SPEED DRIVER 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 : Reading driver information ; Out: ON [DE] RECORD TITLE ; Drivers (up to 80 characters) ; ENDS 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 GENAME_MODEM ; Read the status of lines / DRIVER ; In: [A] Border color ; Out: [A] - DATA FOR PORT # FE , TK Border color + control bits ; LINE AND EXIT LINES ; [B]: bit-: , 0 STATUS LINES (free / busy) 3 availability of touchtone , 4 TUBRO SWITCH OFF IN DRIVERS CHALLENGE , 5 The line , 6 AVAILABLE TIMER , 7 HOURS OF AVAILABILITY 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 ; SWITCH OFF TURBO, IS MANAGEMENT LINE, ; NO HOURS TIMER OR% 00110000 ELSE ; SWITCH OFF THE TURBO, NO CONTROL LINE, ; NO HOURS TIMER, HANDSET WITHDRAW OR% 00010001 ENDIF LD B, A POP AF: RET ; WITHDRAW PIPE D_ON_LINE LD A, # 20: JR ON_OFF_L ; Hang D_OFF_LINE XOR A ON_OFF_L ; CHANGE STATUS LINE, IF NO ; CONTROL LINE - RETURN IMMEDIATELY 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 ; Dialed TUBE already removed ; In: ; [HL] - Address of buffer NUMBER ; [A] - 0 pulse, a tone ; [B] pulse period ms, typ. 100 ; [C] mezhtsifrovaya pause ms/10 ; CY = 1 Error, error code [A]: ; 0 error DIALING ; 1 NO slow beeps 2 INTERRUPT ; CY = 0 Connection established: ; Returns data from both SET_CON_P D_CALL IF CALLING LD (ID_CALL +1), HL PUSH BC ; SETS P / P SCAN LINES XOR A: CALL D_WAIT_INS POP BC LD A, C: LD (CDEL_COD +1), A ; ASK pulse period, by the standards , Gives 2 / 5 PERIOD LINE closed And 3 / 5 PERIOD LINE OPEN ; DIVISIBLE PERIOD TO 5 LD A, B: LD B, 0 DIV5SUB 5: JR C, EDIV5 INC B: JR DIV5 -EDIV5 INC B: DEC B: JR NZ, $ +3: INC B LD A, B: RLCA; 2 / 5 PERIOD LD (CDEL_1 +1), A ADD A, B; 3 / 5 PERIOD LD (CDEL_0 +1), A ; Writes a value to be issued PORT ; # FE for closing / opening LINES LD A, (BORDER_0 +1): AND # 0F LD (DCAL_OFF +1), A LD A, (BORDER_1 +1): OR # 20 LD (DCAL_ON +1), A ; MASENKAYA Pause before dialing EI: LD B, 45: HALT: DJNZ $ -1 ; CONTROL slow beeps: ; Making 200 SURVEY LINE IF ; CATCH 30 consecutive BUZZER - ALL OK LD BC, 200 * 256 30 WAIT_DIA CALL WAIT_CALL JR C, DWAIT_R; Toots NO DEC C JR Z, ID_CALL; CATCH 30 times JR DWAIT_N And if at least once LOST BUZZER - Charter; VIT COUNTER AGAIN AT 30 DWAIT_R LD C, 30 And if pressing the space bar - EXIT DWAIT_N LD A, # 7F: IN A, (# FE) RRCA: JR NC, BRK_CALL DJNZ WAIT_DIA NO_DIAL LD A, 1: SCF: RET; NO SIGNAL -BRK_CALL LD A, 2: SCF: RET; INTERRUPT ERRD_CALL XOR A: SCF: RET; ERROR ED_CALL XOR A: RET; number is entered ; Own set NUMBERS / ID_CALL LD HL, 0; HERE TO ADDRESS BUFFER LD A, (HL): INC HL LD (ID_CALL +1), HL OR A; Find the code # 00 JR Z, ED_CALL; Ending SET , The symbol "-", "(" ")", "" ignoring 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 it's not numbers - type error , Figure "0" corresponds to 10 pulses JR NZ, $ +4: LD A, 10 CP 11: JR NC, ERRD_CALL LD B, A ; RECRUITED figures, in [B] NUMBER OF PULSES CALL_C ; BREAK LINE 60ms (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 ; SHORT LINE AND BREAK 40ms (2 / 5) DCAL_ON LD A, 0 OUT (# FE), A ; DELAY IN [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 ; MEZHTSIFROVAYA Pause 600ms 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 And if pressing the space bar - LEAVING, AKA RECRUITED ; NUMBER ON LD A, # 7F: IN A, (# FE) RRCA: JR NC, BRK_CALL JR ID_CALL ; Examine 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 BC ; CONTROL Toots, average. Arithmetic. ; VALUE RATE FOR THE 1932 SURVEY 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 ; In the range 150 ... 250 - FREQUENCY Toots CP 150: RET C CP 250: CCF RET XOR A: SCF: RET ENDIF ; Called when DETECTED BELL. , Picks up the receiver. + Caller ID ; (HERE MISSING!) ; Out: MOD_BUFF NUMBER IN ASCII, END 0 D_AON CALL D_ON_LINE LD B, 75: EI: HALT: DJNZ $ -2: DI , After removing the Handset Pause 1.5 sec. , IF ANY AON, then he can determine ; NUMBER ; Throws MODEM MESSAGE IN BUFFER ; On Off-hook MOD_BUFF3 EQU $ +1: LD DE, # 1111 LD HL, AON_TXT LD BC, EAON_TXT-AON_TXT LDIR RET AON_TXT DB 13, "The modem is connected to the line, 13.0 EAON_TXT ; Two following the P / P USED ; AS "stub", as Auto Algorithm ; RATE IS NOT Ponders ; Establish a connection, transfer , TE IN THE BEGINNING "Send", then "LISTEN" SET_CON_A ; Establish a connection, the reception , TE FIRST LISTEN, THEN "Send" SET_CON_P MOD_BUFF4 EQU $ +1: LD DE, 0 IF CALLING PUSH HL LD (HL), 13: LD BC, 1: XOR A CALL D_TRANSMIT POP HL ENDIF ; Pairing ; In MOD_BUFF Returns a text Messaging. ; The connection at the end - RCD # 00 , V [A] set speed, OR # 80 And if it Undefined LD HL, CARR_TXT LD BC, ECARR_TXT-CARR_TXT LDIR LD A, # 80; SPEED Undefined RET CARR_TXT DB 13, "set to bridge the" 13.0 ECARR_TXT ; INSTALLATION BEFORE SCAN LINES ; In [A] - VOLUME AUDIO OUTPUT LINE ; THROUGH 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 GD_WAIT_INS1 XOR A: LD (LAST_DT +1), A LD (COUNT0 +1), A LD (COUNT1 +1), A LD (LAST0 +1), A LD (OFFCOU +1), A RET ; SCAN LINES ; Out ; CY = 1: NOTHING ; [B] NUMBER OF CYCLES SURVEY ; [C] How many SHOULD BE CYCLES ; CY = 0,; [A] - CODE: , 1 - APPROVED UNIT, 2 - Activities 3 - A CHALLENGE 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 ; POLL LINE UNIT AND CLOCK ; CONTROL KOTOTKIH Gudkov, BEGINNING , Is considered average. Arithmetic. SIGNIFICANCE OF FREQUENCY ; For 16 POLLS MDLOOP1 IN A, (# FE): AND # 20 ; ANALYSIS / NO ALARM CALL IF CALLING JP Z, RING: ELSE: JP $ +3 ENDIF CALL IN_LINE_F CP 1911: JP C, MDLOOP2 CP 1989: 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 L SRA H: RR L: SRA H: RR L LD A, L: SRA A ; In the range 150 ... 250 - FREQUENCY Toots And if a dial tone, then A = 1 OTHERWISE 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 Comp. Signal does not change, ; Simply increase COUNTER. IF ; Change, then SWITCH 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 changing: NEW_DTL DEC A: JR Z, NEW_DTL1 , Became "0": Switch COUNTER LD HL, COUNT0 +1: LD (HL), 0 LD (ADR_IDL +1), HL , IF> 4 One unit> 4 zeros in succession, ; MEAN CATCH Last post COUNT1 LD A, 0: CP 4: JP C, RES_OFF LAST0 LD A, 0: CP 4: JP C, RES_OFF ; CAUGHT 3 beeps RETIRE OFFCOU LD A, 0: INC A: LD (OFFCOU +1), A CP 3: JR Z, BUSY_FOUND ; SPEED STEEL "1": Switch COUNTER NEW_DTL1 LD HL, COUNT1 +1: LD (HL), 0 LD (ADR_IDL +1), HL COUNT0 LD A, 0 JPE_WAIT_LN LD (LAST0 +1), A JR E_WAIT_LN RES_OFF XOR A LD (COUNT0 +1), A LD (COUNT1 +1), A JR JPE_WAIT_LN BUSY_FOUND OR A: LD A, 2; CY = 0, A = 2 "BUSY" RET ; CATCH CALL FOR A REALITY CHECK ; IF SIGNAL CALL WILL KEEP ; Some time - THEN CALL IN NATURE GRINGLD C, 2 RING1 LD B, 30: NOP: DJNZ $ -1 IN A, (# FE): AND # 20 JP NZ, D_WAIT_LN DEC C: JR NZ, RING1 ; CALL IS EXPECTED ITS END RING2 IN A, (# FE): AND # 20: JR Z, RING2 LD A, 3; CY = 0, A = 3 "BELL" RET E_WAIT_LN LD BC, # 0101 SCF: RET; CY = 1 - nothing ; POLL hold: [A] TO FREQUENCY SIGNAL 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 ; CATCH CLOCK, TAKE THE 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 Successful TOOK THE BLOCK OR A: LD A, 1 RET ; Long wait UNIT AND RECEIVING UNIT ; Out: CY NO BLOCK ; [BC] LENGTH ; [D] SPEED (# 80 unknown) 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; DELAY AND SURVEY ENTRY PUSH BC: POP BC ; SURVEY ENTRY 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 ; PENDING RELEASE OF LINE, VERT ; Here as long as the lines are not ; Disappear SUBSCRIBER SIGNAL 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_FREE3 DEC B: JP Z, LINE_FREE4 CP # FF: JP NC, LINE_FREE4 CALL DELAY_37 CALL SCAN_IN JP C, LN_FREE3 JP LN_FREE2 , The line is free LINE_FREE4 POP BC: POP DE: POP AF RET ; TIMING UNIT 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 ON PASS. The number of cycles 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 , Waiting for a signal SUBSCRIBER ; During 2 ... 4 seconds WAIT_LINE DI LD HL, # 4000: LD (LCOUNT_A), HL LD D, 3 WT_LINE1 LD E, 3 WT_LINE2 LD H, 1 WT_LINE3 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_LINE3 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 ; SPEED CONTROL IN WAITING WAIT_SPEED CALL DELAY_47: NOP DEC B: JP NZ, LP_WLINE CALL IN_LINE ; Speed control. Counting the number of pulses, SOI => SPEED 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 ; RECEPTION UNIT. ; In [B] The number of pulses (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; 2400 CALL SYNC_FAST: RET C CALL LOAD_BYTE_FAST: RET C And the taking of block length: if 0-byte ; Equals # 08, then the length UNIT FOR MORE ; 256 bytes LD (ZERO_BYTE), A LD D, 0 CP 8: JR NZ, $ +3: INC D And the taking of the MLS. Length Byte CALL LOAD_BYTE_FAST: RET C LD E, A: OR A: JR NZ, $ +3: INC D LD (BLOCK_LEN), DE And the taking of the block, LONG [DE] GLD_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 ; ACCEPT BYTES LOAD_BYTE_FAST LD B, 8; We catch 8-bit CALL IN_LINE ; Determine the frequency, if it lies ; In the range from MIN to MAX, the bit ; ACCEPTED, AKA - ERROR CP MIN: JP C, ERR_LDFAST CP MAX: JP NC, ERR_LDFAST ; IF frequency is greater than ZERO - ADOPTED ; UNIT LESS - ZERO CP ZERO RL C; TOOK INVERTED 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; INVERTED BYTES PUSH AF CALL IN_LINE POP AF OR A: RET; BYTES ACCEPTED ERR_LDFAST; receive error POP BC SCF: RET ; TIMING UNIT 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 ;! For the rate of 1800/600 are all very , LIKE, SO NO COMMENT 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 ; Receives long CALL LOAD_BYTE_1800: RET C LD E, A: OR A: JR NZ, $ +3: INC D LD (BLOCK_LEN), DE GLD_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 ; Receives long 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 GLOAD_BYTE_600 PUSH DE: PUSH BC LD B, 8 CALL IN_LINE CALL IN_LINE CALL IN_LINE CP # 17: JP C, ERR_LD600 CP # 59: JP NC, ERR_LD600 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_LD600 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 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 ; TRANSFER UNIT FROM MOD_BUFF, ; BC - LENGTH, A - SPEED D_TRANSMIT DI LD (SPEED), A PUSH AF; keep your speed MOD_BUFF2 EQU $ +1: LD HL, 0 DEC HL PUSH HL ADD HL, BC EX (SP), HL; Ambassador. BYTE LD (HL), C; MLS. Length Byte DEC HL: LD (HL), 7 LD A, B: OR A JR Z, $ +3: INC (HL); LENGTH> 256 DEC HL LD (HL), # AA; SYNC BYTES XOR A DEC HL: LD (HL), A DEC HL: LD (HL), A DEC HL POP DE; ADDRESS OF LAST BYTE POP AF; RATE OR A: JP Z, TRANSMIT_600 DEC A: JP Z, TRANSMIT_1800 GTRANSMIT_FAST XOR A: LD (HL), A; SYNCHRO 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 , Gives BLOCK OUTPUT_FAST LD A, (HL); Bytes sent CALL OU_BYTE_FAST NOP CALL COMP_HL_DE RET Z; block is transferred INC HL: JP OUTPUT_FAST ; TRANSFER BYTE 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 ; When transferring 1-th bit MIC OFF FOR LESS , 12 (168 cycle), because 168 CTTA NEEDED ; To obtain the next. BYTE, CONTROL, ... GOB_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 ; LIKE FOR 1800/600 GTRANSMIT_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 GOB_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_BIT600 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_BIT600 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_BIT600 POP DE: POP HL RET To compare the 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; frequency for "0" D1_1800 DB 67,67 +13; FREQUENCY FOR "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; TRANSFER CODE "0" D1_FAST DB 51,51 +13; SPEED FAST "1" MIN EQU 11 MAX EQU 37 GZEROEQU 23 , The number of ticks in the TRANSFER BIT ; T = (2 * D +13) * 14 +56 D - NUMBER OF TABLES ; D0_?? FOR TRANSMISSION "0" and D1_?? FOR "1" ; AVERAGE SPEED: ; SPEED = (SPD0 + SPD1) / 2 ; SPD0 = 3500000/T0 SPD1 = 3500000/T1 ; RECEIVER: And if the line relevant number <MIN-ERROR And if> MAX: ERROR , If MIN
Other articles:
Similar articles:
В этот день... 21 November