|
@@ -0,0 +1,297 @@
|
|
1
|
+;*** PrScale ROUTINE CALLED AT END OF AttnSig AND Srq SIGNALS
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+PreScale8
|
|
5
|
+ banksel OPTION_REG
|
|
6
|
+ movlw b'00000010' ; BINARY - set to prescale RTCC
|
|
7
|
+ movwf OPTION_REG ; Clear 4th bit from right to select RTCC
|
|
8
|
+ banksel TMR0
|
|
9
|
+ clrf TMR0 ; last 3 bits set prescale value as 1:4
|
|
10
|
+ retlw 00h ; this gives a good ratio to monitor the
|
|
11
|
+ ; timing for Reset and Attention signals and
|
|
12
|
+ ; the 2nd Application Task
|
|
13
|
+
|
|
14
|
+;*** NoPrScl ROUTINE CALLED AT BEGINNING OF SyncSig AND END OF Srq SIGNALS
|
|
15
|
+PreScale2
|
|
16
|
+ banksel OPTION_REG
|
|
17
|
+ movlw b'00000000' ; BINARY - set to prescale RTCC
|
|
18
|
+ movwf OPTION_REG ; Clear 4th bit from right to select RTCC
|
|
19
|
+ banksel TMR0
|
|
20
|
+ clrf TMR0 ; last 3 bits set prescale value as 1:4
|
|
21
|
+ retlw 00h ; this gives a good ratio to monitor the
|
|
22
|
+ ; timing for Reset and Attention signals and
|
|
23
|
+ ; the 2nd Application Task
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+;***************************************************************************
|
|
27
|
+
|
|
28
|
+;*** GET INCOMING BIT & INTERPRET WHETHER IT'S A '1' OR A '0' *** (Get_Bit) ***
|
|
29
|
+;*** Get_Bit CALLED BY COMMAND AND LISTEN ROUTINES
|
|
30
|
+; Get the bit, find out whether it's less than or greater than 50 usecs,
|
|
31
|
+; if < than 50 usecs, it's a '1' bit
|
|
32
|
+; if > than 50 usecs, it's a '0' bit
|
|
33
|
+; if it's a '1' bit, set LSB in the reg. pointed to by the FSR (Command Byte)
|
|
34
|
+; if it's a '0' bit, do nothing to the LSB
|
|
35
|
+; then look for the end of the Bit Cell (104 usecs max.)
|
|
36
|
+; if the maximum Bit time of (72 usecs) or maximum Bit Cell time is exceeded,
|
|
37
|
+; abort to the Attn Signal
|
|
38
|
+
|
|
39
|
+Get_Bit banksel TMR0
|
|
40
|
+ movf TMR0,w ; Check the time, then check if the line went high:
|
|
41
|
+ subwf TimeVar,w ; See if more than BIT_TST usecs have passed
|
|
42
|
+ btfss STATUS,C ; if not, check whether the line went high
|
|
43
|
+ goto AttnSig ; if so, abort to the Attn Signal
|
|
44
|
+ btfss PORTA,ADBPin ; Check whether the line went high
|
|
45
|
+ goto Get_Bit ; if line is still low, loop again
|
|
46
|
+ movlw BIT_TST ; if line went high, see if it's a '1' or a '0'
|
|
47
|
+ movwf TimeVar ; as the bit has not yet been determined yet,
|
|
48
|
+ bcf INDF,0 ; ensure the LSB in the indirect address is '0'
|
|
49
|
+ movf TMR0,W ; Get the time
|
|
50
|
+ subwf TimeVar,W ; if time < 50 usecs, it's a '1' bit
|
|
51
|
+ btfsc STATUS,C ; if time > 50 usecs and < 72, it's a '0' bit
|
|
52
|
+ bsf INDF,0 ; if it's a 1, set LSB in the address FSR points to
|
|
53
|
+ movlw BITCELL ; Check whether the Max. Bit Cell time of 104 usecs
|
|
54
|
+ movwf TimeVar ; has been exceeded
|
|
55
|
+CellChk movf TMR0,W ; Check the time, then check the line
|
|
56
|
+ subwf TimeVar,W ; See if more than Max. Bit Cell usecs have passed
|
|
57
|
+ btfss STATUS,C ; if not, look for the line to go low again
|
|
58
|
+ goto AttnSig ; if so, abort to the Attn Signal or Reset
|
|
59
|
+ btfsc PORTA,ADBPin ; Check the line for the start of another bit
|
|
60
|
+ goto CellChk ; if the line is still high, loop CelChk1 again
|
|
61
|
+ clrf TMR0 ; if the line went low, clear the RTCC & return
|
|
62
|
+ retlw 00h ; for another bit or to interpret the Command
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+;***************************************************************************
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+;*** MASK OUT COMMAND NIBBLE AND REG.# BITS FROM THE COMMAND *** (MaskCmd) ***
|
|
72
|
+; NOTE: This routine should only be called once during any single ADB
|
|
73
|
+; transaction, from either AddrChk or CmmdChk
|
|
74
|
+
|
|
75
|
+; Command Byte:
|
|
76
|
+; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
77
|
+; | A3 | A2 | A1 | A0 | Cmd Code | Register |
|
|
78
|
+
|
|
79
|
+DecodeCmd
|
|
80
|
+ assume bank0
|
|
81
|
+
|
|
82
|
+ movf CmdByte, w
|
|
83
|
+ andlw 0xF0
|
|
84
|
+ movwf ReqAddress
|
|
85
|
+ swapf ReqAddress, f
|
|
86
|
+
|
|
87
|
+ movf CmdByte, w
|
|
88
|
+ andlw 0x03
|
|
89
|
+ movwf ReqReg
|
|
90
|
+ addwf ReqReg, w ; multiply reg by 2 to get 16 bit register offset
|
|
91
|
+ addlw Reg0a ; add base address of register memory area
|
|
92
|
+ movwf RAMaddr ; store pointer
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+ call SetCmdFlags ; use a jump table to translate the 16
|
|
96
|
+ movwf ReqCommand ; possible combinations of commands into a
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+ ; turn ReqReg into bit field so we can use btfss elsewhere
|
|
100
|
+
|
|
101
|
+ btfsc ReqReg, 1
|
|
102
|
+ goto $+5
|
|
103
|
+ movlw 0x01 ; 00
|
|
104
|
+ btfsc ReqReg, 0
|
|
105
|
+ movlw 0x02 ; 01
|
|
106
|
+ goto storVal
|
|
107
|
+ movlw 0x04 ; 10
|
|
108
|
+ btfsc ReqReg, 0
|
|
109
|
+ movlw 0x08 ; 11
|
|
110
|
+storVal movwf ReqReg
|
|
111
|
+
|
|
112
|
+ return
|
|
113
|
+
|
|
114
|
+SetCmdFlags
|
|
115
|
+
|
|
116
|
+ movf CmdByte, w
|
|
117
|
+ andlw 0x0F
|
|
118
|
+ addlw SetCmdFlagsJump
|
|
119
|
+
|
|
120
|
+SetCmdFlagsJump
|
|
121
|
+
|
|
122
|
+ retlw 1<<cmdReset ; 0
|
|
123
|
+ retlw 1<<cmdFlush ; 1
|
|
124
|
+ retlw 1<<cmdReserved ; 2
|
|
125
|
+ retlw 1<<cmdReserved ; 3
|
|
126
|
+ retlw 1<<cmdReserved ; 4
|
|
127
|
+ retlw 1<<cmdReserved ; 5
|
|
128
|
+ retlw 1<<cmdReserved ; 6
|
|
129
|
+ retlw 1<<cmdReserved ; 7
|
|
130
|
+ retlw 1<<cmdListen ; 8
|
|
131
|
+ retlw 1<<cmdListen ; 9
|
|
132
|
+ retlw 1<<cmdListen ; A
|
|
133
|
+ retlw 1<<cmdListen ; B
|
|
134
|
+ retlw 1<<cmdTalk ; C
|
|
135
|
+ retlw 1<<cmdTalk ; D
|
|
136
|
+ retlw 1<<cmdTalk ; E
|
|
137
|
+ retlw 1<<cmdTalk ; F
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+;***************************************************************************
|
|
147
|
+
|
|
148
|
+;*** ISSUE A SERVICE REQUEST IF NECESSARY *** (Srq; may call LineLow) ***
|
|
149
|
+;*** CALLED BY AddrChk
|
|
150
|
+; see if the Srq Flag is set, if not, return, otherwise:
|
|
151
|
+; change the prescaler to RTCC since this takes longer than 255 usecs,
|
|
152
|
+; load the SRQTIME of 300 usecs into the TimeVariable,
|
|
153
|
+; call LineLow to:
|
|
154
|
+; keep checking the time to see if 300 usecs have passed,
|
|
155
|
+; let the line go high again,
|
|
156
|
+; and see if the line is high, and if not, abort, if it is,
|
|
157
|
+; change the prescaler back to WDT, and return
|
|
158
|
+
|
|
159
|
+SendSrq
|
|
160
|
+ call PreScale8 ; switch the prscaler to RTCC
|
|
161
|
+ banksel TRISA
|
|
162
|
+ bcf TRISA, ADBPin ; tri-state PORTA to make the ADB an output
|
|
163
|
+ movlw SRQ_MAX
|
|
164
|
+ call LineLow
|
|
165
|
+ call PreScale2 ; change the prescaler back to WDT
|
|
166
|
+ return
|
|
167
|
+
|
|
168
|
+;***************************************************************************
|
|
169
|
+
|
|
170
|
+;*** Tlt - TIME FROM STOP BIT TO START BIT *** (Tlt) ***
|
|
171
|
+;*** CALLED BY EITHER Talk OR Listen ROUTINES
|
|
172
|
+; Loop checking the time, then checking the line to see if it went low
|
|
173
|
+; if at any time the line goes low,
|
|
174
|
+; see if this is a Talk Command,
|
|
175
|
+; if it is a Talk Commmand, go to the Collision routine
|
|
176
|
+; if the line goes low before the minimum Tlt time, abort to Attn Signal
|
|
177
|
+; if the line is high longer than TLT_Min usecs,
|
|
178
|
+; see if this is a Talk Command, and if it is, wait for the mid-point,
|
|
179
|
+; and return to Send the Start Bit, Data Bytes, & the Stop Bit
|
|
180
|
+; if it's not a Talk Command, see if it's a Listen Command, and if so,
|
|
181
|
+; load Tlt_Max for TimeVariable, and look for the line to go
|
|
182
|
+; low as the beginning of the Start Bit,
|
|
183
|
+; if more than Tlt_Max usecs pass, abort to Attn Signal
|
|
184
|
+; if the line goes low and this is a Listen Command,
|
|
185
|
+; clear the RTCC & return to get the rest of the Start Bit
|
|
186
|
+
|
|
187
|
+Tlt movlw TLT_MIN ; Look for Stop-to-Start-Time, Tlt
|
|
188
|
+ banksel TimeVar
|
|
189
|
+ movwf TimeVar ; Check the time, then check the line
|
|
190
|
+TltChk1 movf TMR0,W ; See if more than TLT_MIN usecs have passed
|
|
191
|
+ xorwf Random,F ; (ensure the Talk R3 address is Random with XOR)
|
|
192
|
+ subwf TimeVar,W ; by checking whether Carry bit is set
|
|
193
|
+ btfss STATUS,C ; after subtraction
|
|
194
|
+ goto ChkFlag ; if TLT_MIN usecs passed, see what Command this is
|
|
195
|
+ btfsc PORTA, ADBPin ; if not, check whether the line went low
|
|
196
|
+ goto TltChk1 ; if the line is still high, keep looping
|
|
197
|
+ btfsc Flags1,F1Talk ; if line went low, see if this is a Talk Command
|
|
198
|
+ goto Collisn ; if it is, there was a Collision, abort
|
|
199
|
+ movf TMR0,W ; otherwise, check the time
|
|
200
|
+ subwf TimeVar,W ; see if TLT_MIN usecs passed,
|
|
201
|
+ btfss STATUS,C ; if not, abort to Attn Signal, too little
|
|
202
|
+ goto AttnSig ; time passed when the line went low
|
|
203
|
+ clrf TMR0 ; if it's not a Talk Command, clear the RTCC and
|
|
204
|
+ retlw 00h ; return for the rest of the Start Bit
|
|
205
|
+
|
|
206
|
+ChkFlag banksel Flags1
|
|
207
|
+ btfsc Flags1,F1Talk ; Check whether to Talk or Listen
|
|
208
|
+ goto TltTalk ; if Talk, wait for mid-point of Tlt time
|
|
209
|
+ btfss Flags1,F1Lstn ; if Listen, continue to look for Start Bit
|
|
210
|
+ retlw 00h ; if neither flag is set, abort, something's wrong
|
|
211
|
+ movlw TLT_MAX ; Load TimeVariable to check for upper limit
|
|
212
|
+ movwf TimeVar ; of Tlt time
|
|
213
|
+TltChk2 movf TMR0,W ; See if TLT_MAX usecs have been exceeded
|
|
214
|
+ subwf TimeVar,W ; by checking whether Carry bit is set
|
|
215
|
+ btfss STATUS,C ; after subtraction
|
|
216
|
+ goto AttnSig ; if so, abort to Attn Signal
|
|
217
|
+ btfsc PORTA,ADBPin ; if not, check whether the line went low
|
|
218
|
+ goto TltChk2 ; if line is still high, check the time again
|
|
219
|
+ btfsc Flags1,F1Talk ; if line went low, see if this is a Talk Command
|
|
220
|
+ goto Collisn ; if so, there was a Collision
|
|
221
|
+ clrf TMR0 ; if it's not a Talk Command, return to get
|
|
222
|
+ retlw 00h ; the rest of the Start Bit from Host
|
|
223
|
+
|
|
224
|
+TltTalk movlw TLT_MID ; Load TimeVariable so Talk will send Start Bit at
|
|
225
|
+ banksel TimeVar
|
|
226
|
+ movwf TimeVar ; about the mid-point of the Tlt
|
|
227
|
+TltChk3 movf TMR0,W ; See if TLT_MID usecs have been exceeded
|
|
228
|
+ subwf TimeVar,W ; by checking whether Carry bit is set
|
|
229
|
+ btfss STATUS,C ; after subtraction
|
|
230
|
+ retlw 00h ; if time was exceeded, return to send Start Bit
|
|
231
|
+ btfsc PORTA, ADBPin ; if not, check whether the line went low
|
|
232
|
+ goto TltChk3 ; if line is still high, check the time again
|
|
233
|
+ goto Collisn ; if the line went low, abort to Collision
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+Collisn banksel bank1
|
|
237
|
+ btfsc ReqReg, 3 ; if there was a collision during a Talk Reg. 3
|
|
238
|
+ bsf Flags1, F1Cllsn ; Command, then set the Collision Flag,
|
|
239
|
+ goto AttnSig ; otherwise, just abort to Attn Signal
|
|
240
|
+
|
|
241
|
+;***************************************************************************
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+SendLow
|
|
245
|
+ movlw LOW0BIT ; Send a '0' bit
|
|
246
|
+ call LineLow ; hold the line low for 2/3rd of a Bit Cell
|
|
247
|
+ movlw HI_0BIT
|
|
248
|
+ call LineHi ; let the line high for the rest of the Bit Cell
|
|
249
|
+ return
|
|
250
|
+
|
|
251
|
+SendHigh
|
|
252
|
+ movlw LOW1BIT ; Send a '1' bit
|
|
253
|
+ call LineLow ; hold the line low for 1/3rd of a Bit Cell
|
|
254
|
+ movlw HI_1BIT
|
|
255
|
+ call LineHi ; let the line high for the rest of the Bit Cell
|
|
256
|
+ return
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+;*** MAKE LINE GO LOW TIME IN TimeVar AS A '1' OR '0' BIT *** (LineLow) ***
|
|
263
|
+;*** CALLED BY Talk OR Srq
|
|
264
|
+
|
|
265
|
+LineLow movwf TimeVar
|
|
266
|
+Low_Tmp movf TMR0,W ; Check the clock,
|
|
267
|
+ subwf TimeVar,W ; loop until TimeVar usecs have passed
|
|
268
|
+ skpnc
|
|
269
|
+ goto Low_Tmp
|
|
270
|
+ banksel bank1 ; Tri-state PORTA to make ADB line an input again
|
|
271
|
+ bsf TRISA, ADBPin ; and let the line go high
|
|
272
|
+ banksel bank0
|
|
273
|
+ clrf TMR0 ; and clear RTCC
|
|
274
|
+ goto $+1 ; Allow the ADB Port line to stabilize
|
|
275
|
+ goto $+1 ; Allow the ADB Port line to stabilize
|
|
276
|
+ btfss PORTA, ADBPin ; check if the line is still low, if so, a
|
|
277
|
+ goto Collisn ; Collision occurred
|
|
278
|
+ retlw 00h ; if not, return to load high time for rest of bit
|
|
279
|
+
|
|
280
|
+;*** MAKE LINE GO HIGH FOR REST OF BIT CELL TIME IN TimeVar *** (LineHi) ***
|
|
281
|
+;*** CALLED BY Talk
|
|
282
|
+
|
|
283
|
+LineHi movwf TimeVar ; Let the line go high for a pre-designated time
|
|
284
|
+Hi_Tmp movf TMR0,W ; Check the clock,
|
|
285
|
+ subwf TimeVar,W ; loop until TimeVar usecs have passed
|
|
286
|
+ skpnc
|
|
287
|
+ goto Hi_Tmp
|
|
288
|
+ btfss PORTA, ADBPin ; check if the line is still high,
|
|
289
|
+ goto Collisn ; if not, a Collision occurred, Abort
|
|
290
|
+ btfsc Flags1,F1Stop ; if this is the end of the Data Stop Bit, don't
|
|
291
|
+ retlw 00h ; let the line go low again, just return
|
|
292
|
+ banksel bank1 ; if still high, start sending a bit to the Host
|
|
293
|
+ bcf TRISA, ADBPin ; tri-state PORTA to make the ADB an output and
|
|
294
|
+ banksel bank0
|
|
295
|
+ clrf TMR0
|
|
296
|
+ retlw 00h
|
|
297
|
+
|