설명 없음

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