┌---------------------------------------┐
│░░░░░░░░░░ 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