home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / packetdrivers.tar.gz / pd.tar / src / express.asm < prev    next >
Assembly Source File  |  1995-06-25  |  51KB  |  1,830 lines

  1. version    equ    4
  2.  
  3.     include    defs.asm
  4.     include    8250defs.asm
  5. ;
  6. ;    Dave Price. October 30th 1990. 12:35.
  7. ;    Things much better now. I have had my standard
  8. ;    'FTP' test running at 2.5 Kbytes per second.
  9. ;    There is still a transmit bug though.. It appears
  10. ;    as the transmission of giant packets. I think I know
  11. ;    the source of the bug. I believe it occurs when we are
  12. ;    transmitting the last few bytes of a packet. Before
  13. ;    we change the interrupt mask to expect only TXDONE and
  14. ;    TXURUN, the TX fifo drains so that the TX419 condition
  15. ;    becomes true. The result is that the 8952 is already
  16. ;    waiting to interrupt us with the TX419. My code does not
  17. ;    expect anymore of these and acts incorrectly when
  18. ;    one arrives!
  19. ;
  20. ;    Dave Price. October 30th 1990 10:08.
  21. ;    After several minor changes the driver was almost
  22. ;    working. Some problems still existed however and
  23. ;    transferring data with FTP for instance
  24. ;    seemed to take a very long time. It appeared that
  25. ;    data was being lost, or that the routers or distant
  26. ;    host were so busy that packets were being dropped.
  27. ;    A further possible cause was that the timers used
  28. ;    by the TCP protocol engines were inappropriate or
  29. ;    in some sense incompatible. A carefull reading of
  30. ;    the data sheets implies that one can use the 'FIFO empty'
  31. ;    bits providing you make sure that at least 2 cycles
  32. ;    of a 2mHz clock occur after you read data and before you
  33. ;    read the interrupt flag register. This only amounts to
  34. ;    16 bus cycles on a 16Mhz PC. This is really very few
  35. ;    instructions. I have talked to Jeremy Bicknall at MITEL
  36. ;    and he seems to agree (I reported a potential design
  37. ;    bug with the 8952 generating false RX1519s - he will persue).
  38. ;    I have thus decided to use the RXBYTE bits to decide how
  39. ;    to process each item of data but use the RXFIFO empty state
  40. ;    to cease reading data.
  41. ;
  42. ;
  43. ;    Dave Price. October 24th 1990 11:10.
  44. ;    More changes again. The main idea now is 
  45. ;    to only have two states in the RX protocol engine.
  46. ;    It is either 'building' a frame or 'skipping'
  47. ;    to the next one. The actual interrupts will just
  48. ;    be used to indicate the point at which you should
  49. ;    stop processing the RXFIFO. There will be several
  50. ;    items to help. A minimum numbers of bytes to read,
  51. ;    a maximum number of bytes to read and a stop condition.
  52. ;    Processing the FIFO will cease when either the maximum
  53. ;    number of bytes have been processed, or BOTH the stop
  54. ;    condition and the minimum number have been processed.
  55. ;    On considering a new item of data a mask will be built
  56. ;    containing 5 bits that reflect a condition implied
  57. ;    by the data. Four bits are used to simply indicate
  58. ;    a packet byte, first byte, good last byte or bad last
  59. ;    byte. The fifth bit is used to indicate a frame abort
  60. ;    condition; this can only be determined by deciding
  61. ;    that the byte about to be read is a 'first' byte and
  62. ;    we already BUILDING a packet.
  63. ;    This change is a radical departure from previous
  64. ;    approaches to the RX code and might perhaps work
  65. ;    (HA, Ha!)
  66. ;
  67. ;    Dave Price. October 23rd 1990 16:06.
  68. ;    Some change of thought again.. I hate 8952s!
  69. ;    I am moving to four states in RX protocol engine.
  70. ;    'idle' will mean - finished one packet, awaiting next
  71. ;    'skipping' will mean we failed to get a buffer so
  72. ;    we are awaiting this packet to go by before trying
  73. ;    again for a buffer. I.E. we are discarding all input
  74. ;    waiting for an FA or EOPD etc etc
  75. ;    'found' means that the NEXT byte in the fifo
  76. ;    is a 'first' byte. I.E. here comes the packet...
  77. ;    'building' means we have a buffer and we are off
  78. ;    making up the next packet.
  79. ;
  80. ;    Dave Price. October 23rd 1990 09:40.
  81. ;    Having got completely fed up with lots of minor bugs
  82. ;    in the RX code, I am now carrying on with the changes
  83. ;    started earlier on 17th to attempt to have
  84. ;    some more clean code for the RX side. Most of the
  85. ;    code has been developed over the weekend but is 
  86. ;    handwriiten on the last listing. Problems
  87. ;    mainly arise with odd combinations of events
  88. ;    rather than simple circumstances. A major change is
  89. ;    that the RX code will now longer go and get itself
  90. ;    a buffer until the 'first byte' has been located. In
  91. ;    particular the completion of the collection of one
  92. ;    packet was immediately followed by the allocation
  93. ;    of a new buffer. This will now not happen.
  94. ;    I also intend at a later date to add fields to the
  95. ;    hdlc datastructure to hold port addresses etc. This
  96. ;    will start to pave the way for making the driver handle
  97. ;    multiple channels. It will require other changes as
  98. ;    well though (mainly stopping the code use constructions
  99. ;    like hdlc0.fred and instead move to set bx; [bx].fred.
  100. ;    This is not straightforward though as bs is already
  101. ;    used as a pointer. It will imply lots of pushing and
  102. ;    popping probably. All this is the next fix NOT
  103. ;    this change anyway.
  104. ;
  105. ;    October 17th 1990 20:30. Work starts to alter RX data
  106. ;    structures with a view to adding a 'state' variable
  107. ;    and dealing with input quite differently.
  108. ;
  109. ;    October 17th 1990.
  110. ;    Several new patches of code added to try to
  111. ;    the remaining bugs. Most bugs are caused by too long
  112. ;    packets being received (possibly because rx fails to
  113. ;    deal with FAs and RXOFLOWs correctly).
  114. ;
  115. ;    October 16th 1990. The code has now been used
  116. ;    fairly successfully. Some files have been transfered
  117. ;    using FTP from a sun via one NOS router over a 64Kbps
  118. ;    link from a second NOS PC. The central router had to
  119. ;    be rebooted once during the transfer as the driver
  120. ;    ran out of receive buffers! Amazingly the file
  121. ;    transfered o.k! The file was a 43Kbyte binary
  122. ;    of a virus checking program.
  123. ;    Code has been added to cope with RXofloe and Frame
  124. ;    abort, but bugs exist.
  125. ;
  126. ;    October 11th 1990.  The code has been running now
  127. ;    used by NOS. Some problems had occurred with 
  128. ;    events like txdone also having tx419 set.
  129. ;    Even though only txdone was enabled as an interrupt,
  130. ;    reading the 'interrupt flag register' showed both
  131. ;    bits set. As the code allows for several conditions
  132. ;    to be true it obeyed the one set of code and then 
  133. ;    attempted to handle the other condition too! This
  134. ;    resulted in errors.
  135. ;    The code now carefully processes txdone and then avoids
  136. ;    the tx419 condition!
  137. ;    Similar problems exist with eopd and fa!
  138. ;
  139. ;    October 1st 1990. Code is now in place to handle
  140. ;    rx and tx interrupts. user can also specify -n
  141. ;    so board acts as an NT.
  142. ;    Only RX1519, and EOPD handled on receive and TXDONE and
  143. ;    TX419 handles on transmit.
  144. ;
  145. ;    Buffer strategy Changed again. 25 September 1990. Dave Price
  146. ;    The idea now is that there will be a ring of
  147. ;    structures, each structure containing a little control
  148. ;     information plus a Data Unit in which will be placed
  149. ;    an IP frame (or potentially any other type of frame).
  150. ;    There will be two such rings, one for transmission
  151. ;    and one for reception.
  152. ;    The rings will be statically allocated.
  153. ;    The Data Units will be set at 1500 bytes, the same
  154. ;    as the maximum MTU for ethernet packet drivers.
  155. ;
  156. ;    Simple byte-ring-buffer has proved awkward to
  157. ;    code. One often seems to be fighting the INTEL CPU.
  158. ;    On reflection a 'frame' based approach might be better.
  159. ;
  160. ;    Added Code for RJG suggested Buffer Management. The
  161. ;    idea is described in an ARUW?? document. There will
  162. ;    be a circular ring buffer of bytes (like the slip
  163. ;    drivers) with an associated structure to hold the
  164. ;    state of the buffers.
  165. ;
  166. ;    More bits from Dave Price to initialize
  167. ;    MITEL express card. Just plugs voice so far.
  168. ;    30/8/90
  169. ;
  170. ; This is a hacked version of slip8250 packet driver.
  171. ; The hack is beginning on 28/8/90.
  172. ; First attempts are just to change messages etc!
  173. ;
  174. ;    Changes started by Dave Price
  175. ;
  176. ;Ported from Phil Karn's asy.c and slip.c, a C-language driver for the IBM-PC
  177. ;8250 by Russell Nelson.  Any bugs are due to Russell Nelson.
  178. ;16550 support ruthlessly stolen from Phil Karn's 8250.c. Bugs by Denis DeLaRoca
  179.  
  180. ;  Copyright, 1988-1992, Russell Nelson, Crynwr Software
  181.  
  182. ;   This program is free software; you can redistribute it and/or modify
  183. ;   it under the terms of the GNU General Public License as published by
  184. ;   the Free Software Foundation, version 1.
  185. ;
  186. ;   This program is distributed in the hope that it will be useful,
  187. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  188. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  189. ;   GNU General Public License for more details.
  190. ;
  191. ;   You should have received a copy of the GNU General Public License
  192. ;   along with this program; if not, write to the Free Software
  193. ;   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  194.  
  195. code    segment    byte public
  196.     assume    cs:code, ds:code
  197. ;
  198. ;    Constants etc from MITEL Express card
  199. ;
  200. ;    First the DX (8980)
  201. ;
  202. board_w_dx    dw    0300h
  203.  
  204. dx_b_con        equ    0000h
  205. dx_b_cm_base    equ    0400h
  206.  
  207. dx_con_cmh        equ    00011000b
  208. dx_con_cml        equ    00010000b
  209. dx_cmh_mchan    equ    00000100b
  210. dx_cmh_oe        equ    00000001b
  211.  
  212. ;
  213. ;    Now the stream and channel assignments
  214. ;
  215. snic_stream        equ    6
  216. snic_d_channel    equ    0
  217. snic_c_channel    equ    1
  218. snic_b1_channel    equ    2
  219. snic_b2_channel    equ    3
  220.  
  221. hdlc_stream        equ    6
  222. hdlc_d_channel    equ    4
  223. hdlc_c_channel    equ    5
  224. hdlc_b1_channel    equ    6
  225. hdlc_b2_channel    equ    7
  226. hdlc_b3_channel    equ    8
  227.  
  228. dphone_stream        equ    7
  229. dphone_unused_channel    equ    4
  230. dphone_c_channel        equ    5
  231. dphone_b1_channel        equ    6
  232. dphone_b2_channel        equ    7
  233. dphone_b3_channel        equ    8
  234.  
  235. ;
  236. ;    Now some snic values etc
  237. ;
  238. board_w_snic        dw    0b00h
  239.  
  240. snic_b_master        equ    0000h
  241. snic_b_stbus        equ    0001h
  242.  
  243. snic_master_irqenable    equ    00000000b
  244. snic_master_msdisable    equ    00000010b
  245. snic_master_cstenable    equ    00000000b
  246.  
  247. snic_stbus_all    equ    0ffh
  248.  
  249. snic_c_ar        equ    10000000b
  250. snic_c_dr        equ    01000000b
  251. snic_c_dinb        equ    00100000b
  252. snic_c_priority    equ    00010000b
  253. snic_c_dreq        equ    00001000b
  254. snic_c_txmch    equ    00000100b
  255. snic_c_clrdia    equ    00000010b
  256. snic_c_regsel    equ    00000001b
  257.  
  258. ;
  259. ;    now some dphone values
  260. ;
  261. board_w_dphone    dw    1700h
  262.  
  263. dphone_b_c        equ    0000h
  264. dphone_b_time        equ    0005h
  265. dphone_b_wdog        equ    0006h
  266. dphone_b_tone1        equ    0007h
  267. dphone_b_tone2        equ    0008h
  268. dphone_b_dsp        equ    0009h
  269. dphone_b_trans        equ    000ah
  270. dphone_b_rgain        equ    000bh
  271. dphone_b_sddata    equ    000ch
  272. dphone_b_sddir        equ    000dh
  273. dphone_b_test        equ    000eh
  274.  
  275. dphone_sddir_allout    equ    0ffh
  276. dphone_sddata_te    equ    0b0h
  277. dphone_sddata_nt    equ    0b8h
  278.  
  279. dphone_time_pcmb1    equ    00000001b
  280. dphone_time_pcmb2    equ    00000100b
  281. dphone_time_pcmb3    equ    00010000b
  282.  
  283. dphone_time_c        equ    10000000b
  284.  
  285. dphone_tone_697        equ    59h
  286. dphone_tone_1209        equ    9bh
  287.  
  288. dphone_test_disable    equ    00h
  289.  
  290. dphone_dsp_cpcmen        equ    01000000b
  291. dphone_dsp_dpcmen        equ    00100000b
  292. dphone_dsp_dual        equ    00001000b
  293. dphone_dsp_tone        equ    00010000b
  294. dphone_dsp_speaker    equ    00011000b
  295. dphone_dsp_cadence    equ    00000100b
  296. dphone_dsp_warble16    equ    00000010b
  297. dphone_dsp_dspen        equ    00000001b
  298.  
  299. dphone_trans_dial        equ    00100000b
  300. dphone_trans_side        equ    00010000b
  301. dphone_trans_hsmic    equ    00001000b
  302. dphone_trans_spmic    equ    00000100b
  303. dphone_trans_spskr    equ    00000010b
  304. dphone_trans_hsskr    equ    00000001b
  305.  
  306. dphone_rgain_hpf        equ    10000000b
  307. dphone_rgain_rfg_m7    equ    01110000b
  308.  
  309. ;
  310. ;    now the hdlcs relative to the board base
  311. ;
  312. board_w_hdlc0    dw    0f00h
  313. board_w_hdlc1    dw    1300h
  314. ;
  315. ;    Now register offsets in the hdlc chips
  316. ;
  317. hdlc_br_fifostatus    equ    00h
  318. hdlc_br_receive        equ    01h
  319. hdlc_bw_transmit        equ    01h
  320. hdlc_b_control        equ    02h
  321. hdlc_b_raddress        equ    03h
  322. hdlc_b_cchancontrol    equ    04h
  323. hdlc_b_time            equ    05h
  324. hdlc_br_intflag        equ    06h
  325. hdlc_bw_wdog        equ    06h
  326. hdlc_bw_intenable        equ    07h
  327. hdlc_br_genstatus        equ    08h
  328. hdlc_br_cchanstatus    equ    09h
  329.  
  330. ;
  331. ;    Now some values for the registers of the hdlc's
  332. ;
  333. hdlc_fifostatus_RXBYTE        equ    11000000b
  334. hdlc_fifostatus_packet        equ    00000000b
  335. hdlc_fifostatus_first        equ    01000000b
  336. hdlc_fifostatus_good        equ    10000000b
  337. hdlc_fifostatus_bad        equ    01000000b
  338. hdlc_fifostatus_last        equ    10000000b
  339.  
  340. hdlc_fifostatus_RXFIFO        equ    00110000b
  341. hdlc_fifostatus_rxempty        equ    00000000b
  342. hdlc_fifostatus_rxle14        equ    00010000b
  343. hdlc_fifostatus_rxfull        equ    00100000b
  344. hdlc_fifostatus_rxge15        equ    00010000b
  345.  
  346. hdlc_fifostatus_TXFIFO        equ    00001100b
  347. hdlc_fifostatus_txfull        equ    00000000b
  348. hdlc_fifostatus_txge5        equ    00000100b
  349. hdlc_fifostatus_txempty        equ    00001000b
  350. hdlc_fifostatus_txle4         equ    00000100b
  351.  
  352. hdlc_control_txen        equ    10000000b
  353. hdlc_control_rxen        equ    01000000b
  354. hdlc_control_rxad        equ    00100000b
  355. hdlc_control_ra6        equ    00010000b
  356. hdlc_control_iftf1    equ    00001000b
  357. hdlc_control_iftf0    equ    00000100b
  358. hdlc_control_fa        equ    00000010b
  359. hdlc_control_eop        equ    00000001b
  360.  
  361. hdlc_control_idle        equ    00000000b
  362. hdlc_control_iftf        equ    00000100b
  363. hdlc_control_trans    equ    00001000b
  364. hdlc_control_goahead    equ    00001100b
  365.  
  366. hdlc_time_rst        equ    10000000b
  367. hdlc_time_ic        equ    01000000b
  368. hdlc_time_c1en        equ    00100000b
  369. hdlc_time_brck        equ    00010000b
  370. hdlc_time_tc        equ    00001111b
  371.  
  372. hdlc_time_c2bits8        equ    00000011b
  373. hdlc_time_c3bits8        equ    00000100b
  374. hdlc_time_c4bits8        equ    00000101b
  375. hdlc_time_c23bits16        equ    00000110b
  376. hdlc_time_c234bits24    equ    00000111b
  377.  
  378. hdlc_intflag_ga    equ    10000000b
  379. hdlc_intflag_eopd    equ    01000000b
  380. hdlc_intflag_txdone    equ    00100000b
  381. hdlc_intflag_fa    equ    00010000b
  382. hdlc_intflag_tx419    equ    00001000b
  383. hdlc_intflag_txurun    equ    00000100b
  384. hdlc_intflag_rx1519    equ    00000010b
  385. hdlc_intflag_rxoflw    equ    00000001b
  386.  
  387. hdlc_intenable_ga        equ    10000000b
  388. hdlc_intenable_eopd        equ    01000000b
  389. hdlc_intenable_txdone    equ    00100000b
  390. hdlc_intenable_fa        equ    00010000b
  391. hdlc_intenable_tx419    equ    00001000b
  392. hdlc_intenable_txurun    equ    00000100b
  393. hdlc_intenable_rx1519    equ    00000010b
  394. hdlc_intenable_rxoflw    equ    00000001b
  395.  
  396.  
  397. hdlc_genstatus_rxoflw    equ    10000000b
  398. hdlc_genstatus_txurun    equ    01000000b
  399. hdlc_genstatus_ga    equ    00100000b
  400. hdlc_genstatus_abrt    equ    00010000b
  401. hdlc_genstatus_irq    equ    00001000b
  402. hdlc_genstatus_idle    equ    00000100b
  403.  
  404.  
  405. ;
  406. ;    Now the overall interrupt register
  407. ;
  408. board_w_intreg    dw    1b00h
  409.  
  410. intreg_hdlc0    equ    00000010b    ;bit for hdlc0 interrupt
  411. intreg_hdlc1    equ    00000001b    ;bit for hdlc1 interrupt
  412. intreg_snic    equ    00000100b    ;bit for snic interrupt
  413. intreg_hphone    equ    00001000b    ;bit for d/hphone interrupt
  414. ;
  415. ;    now a few usefull macros
  416. ;
  417. out_chip_reg_value    macro    chip,reg,value
  418.     mov    dx,chip
  419.     add    dx,reg
  420.     mov    al,value
  421.     out    dx,al
  422.     endm
  423.  
  424. in_chip_reg        macro    chip,reg
  425.     mov    dx,chip
  426.     add    dx,reg
  427.     in    al,dx
  428.     endm
  429.  
  430. dx_message    macro    stream,channel,value
  431.     out_chip_reg_value    board_w_dx,dx_b_con,<dx_con_cmh or stream>
  432.  
  433.     out_chip_reg_value    board_w_dx,<dx_b_cm_base or channel>,<dx_cmh_mchan or dx_cmh_oe>
  434.  
  435.     out_chip_reg_value    board_w_dx,dx_b_con,<dx_con_cml or stream>
  436.  
  437.     out_chip_reg_value    board_w_dx,<dx_b_cm_base or channel>,value
  438.  
  439.     endm
  440.  
  441. dx_source    macro    d_stream,d_channel,s_stream,s_channel
  442.  
  443.     out_chip_reg_value    board_w_dx,dx_b_con,<dx_con_cmh or d_stream>
  444.     out_chip_reg_value    board_w_dx,<dx_b_cm_base or d_channel>,dx_cmh_oe
  445.     out_chip_reg_value    board_w_dx,dx_b_con,<dx_con_cml or d_stream>
  446.     out_chip_reg_value    board_w_dx,<dx_b_cm_base or d_channel>,<s_stream shl 5 or s_channel>
  447.  
  448.     endm
  449.  
  450.     public    int_no
  451. int_no        db    7,0,0,0        ; interrupt number.
  452. NT_switch    db    0    ;if 0 be a TE else be an NT
  453.  
  454.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  455. driver_class    db    6,0,0,0        ;from the packet spec
  456. driver_type    db    0,0,0,0        ;from the packet spec
  457. driver_name    db    'EXPRESS',0    ;name of the driver.
  458. driver_function    db    2
  459. parameter_list    label    byte
  460.     db    1    ;major rev of packet driver
  461.     db    9    ;minor rev of packet driver
  462.     db    14    ;length of parameter list
  463.     db    EADDR_LEN    ;length of MAC-layer address
  464.     dw    GIANT    ;MTU, including MAC headers
  465.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  466.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  467.     dw    0    ;(# of successive xmits) - 1
  468.     dw    0    ;Interrupt # to hook for post-EOI
  469.             ;processing, 0 == none,
  470.  
  471. ;
  472. ;    Packet Buffer Structure
  473.  
  474. owner_k_empty    equ    0
  475. owner_k_queue    equ    1
  476. owner_k_isr    equ    2
  477. info_k_size    equ    1500    ;size of info area in buffer
  478. ;
  479. buff        struc
  480. buff_w_next    dw    0    ;pointer to next buffer
  481. buff_w_prev    dw    0    ;pointer to previous buffer
  482. buff_w_size    dw    0    ;size of frame in info area in bytes
  483. buff_w_owner    dw    owner_k_empty    ;current owner of buffer
  484. buff_info    db    info_k_size dup (0)    ;area for the Transfer Unit
  485. buff        ends
  486. ;
  487. ;    Structure for shared Queue Information
  488. ;    Now contains the info for the associated isr routines
  489. ;    as well. 17th October 1990.
  490. ;
  491. ;    First some constants.
  492. ;
  493. state_k_skipping    equ    00000001b
  494. state_k_building    equ    00000010b
  495. upcall_k_idle        equ    0
  496. upcall_k_active    equ    1
  497. ;
  498. hdlc_data        struc
  499. txq_w_front    dw    0    ;pointer to front of tx queue
  500. txq_w_back    dw    0    ;pointer to back of tx queue
  501. rxq_w_front    dw    0        ;pointer to front of rx queue
  502. rxq_w_back    dw    0        ;pointer to back of rx queue
  503. rxupcall_w_state    db    0    ;state of any upcall
  504. rxisr_w_state    db    0    ;the current state of the isr
  505. rxisr_w_pkt    dw    0    ;pointer to the packet being used by rx ISR
  506. rxisr_w_byte    dw    0    ;pointer to the byte the rx ISR will use next    
  507. rxisr_w_count    dw    0    ;count of bytes inserted so far
  508. txisr_w_pkt    dw    0    ;pointer to the packet being used by tx ISR
  509. txisr_w_byte    dw    0    ;pointer to the byte tx ISR will use next
  510. txisr_w_count    dw    0    ;count of bytes remaining
  511. copy_intflag    db    0    ;copy of latest value from int flag
  512. copy_intenable    db    0    ;copy of latest value sent int enable
  513. hdlc_data        ends
  514.  
  515. hdlc0_data    hdlc_data    <offset t1_buff, offset t1_buff, offset r1_buff, offset r1_buff,upcall_k_idle,state_k_skipping>            
  516.  
  517. ;
  518. ;    Names for the bits in the byte_status_mask
  519. ;    rint_status_mask
  520. ;    and the stop_status_mask
  521. ;
  522. mask_k_packet    equ    00000001b
  523. mask_k_first    equ    00000010b
  524. mask_k_good    equ    00000100b
  525. mask_k_bad        equ    00001000b
  526. mask_k_fabort    equ    00010000b
  527.  
  528. byte_status_mask    db    0    ;used to save status implied
  529.                     ;by the current bytes
  530. ;rint_status_mask    db    0    ;used to save status implied
  531.                     ;by the bytes so far in this
  532.                     ;segment in the fifo
  533. ;stop_status_mask    db    0    ;used to specify when we wish
  534.                     ;    to stop
  535. ;
  536. ;    Locations to hold counters of bytes read in
  537. ;    one particular call of the interrupt code.
  538. ;
  539.  
  540. ;number_read        db    0    ;number read so far
  541. ;minimum_read    db    0    ;minimum number that MUST be read
  542.                     ; the interrupt style sets this
  543. ;maximum_read    db    0    ;maximum available
  544.  
  545.     public    rcv_modes
  546. rcv_modes    dw    4        ;number    of receive modes in our table.
  547.         dw    0,0,0,rcv_mode_3
  548.  
  549.  
  550.     public bad_command_intercept
  551. bad_command_intercept:
  552. ;called with ah=command, unknown to the skeleton.
  553. ;exit with nc if okay, cy, dh=error if not.
  554.     mov    dh,BAD_COMMAND
  555.     stc
  556.     ret
  557.  
  558.     public    as_send_pkt
  559. ; The Asynchronous Transmit Packet routine.
  560. ; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
  561. ;   interrupts possibly enabled.
  562. ; Exit with nc if ok, or else cy if error, dh set to error number.
  563. ;   es:di and interrupt enable flag preserved on exit.
  564. as_send_pkt:
  565.     ret
  566.  
  567.     public    drop_pkt
  568. ; Drop a packet from the queue.
  569. ; Enter with es:di -> iocb.
  570. drop_pkt:
  571.     assume    ds:nothing
  572.     ret
  573.  
  574.     public    xmit
  575. ; Process a transmit interrupt with the least possible latency to achieve
  576. ;   back-to-back packet transmissions.
  577. ; May only use ax and dx.
  578. xmit:
  579.     assume    ds:nothing
  580.     ret
  581.  
  582.  
  583.     public    send_pkt
  584. ;
  585.  
  586. send_pkt:
  587. ;enter with es:di->upcall routine, (0:0) if no upcall is desired.
  588. ;  (only if the high-performance bit is set in driver_function)
  589. ;enter with ds:si -> packet, cx = packet length.
  590. ;exit with nc if ok, or else cy if error, dh set to error number.
  591. ;called from telnet layer via software interrupt
  592.     assume    ds:nothing
  593.  
  594.     movseg    es,cs
  595.     assume    es:code
  596.     sti                ; enable interrupts
  597. ;
  598. ;    NOTE Using ES as segment for data accesses
  599. ;
  600.     mov    bx,es:hdlc0_data.txq_w_back    ;get pointer to back of queue
  601.     cmp    es:[bx].buff_w_owner,owner_k_empty    ;is it empty?
  602.     jne    no_buffers_left        ;no so error return...
  603.  
  604.     cmp    cx,info_k_size        ;    check packet size o.k.
  605.     jle    send_pkt_size_ok    ; its fine
  606.     pr_ch_al    'a'            ;    error trace message
  607.     mov    dh,CANT_SEND    ;return an error code
  608.     cli
  609.     stc
  610.     ret
  611.  
  612. send_pkt_size_ok:
  613.     mov    es:[bx].buff_w_size,cx    ;save size
  614.     lea    di,es:[bx].buff_info        ;
  615.     rep    movsb                ;and copy the packet
  616.  
  617.     mov    es:[bx].buff_w_owner,owner_k_queue     ;give it to queue
  618.     mov    bx,es:[bx].buff_w_next    ;point to buffer
  619.     mov    es:hdlc0_data.txq_w_back,bx        ;adjust back of the queue
  620. ;
  621. ;    NOW WE NEED TO PROVOKE LOADING OF TXFIFO
  622. ;    IF WE THINK ISR GONE QUIET
  623. ;
  624. ; structure is at zero no ints active
  625.     cli        ;block interrupts starting before we exit
  626.     cmp    es:hdlc0_data.txisr_w_pkt,0
  627.     je    send_pkt_int_quiet    ; jump if interrupts quiet
  628.     clc                    ;clear carry because all o.k.
  629.     ret
  630. ;
  631. ;    Else we now need to kick the interrupt code
  632. ;
  633. send_pkt_int_quiet:
  634.     push    ds        ;save old ds and make it point to code
  635.     push    cs
  636.     pop    ds
  637.     pr_ch_al    'b'
  638.     call    tint_new        ;manually call the tint routine !
  639.     pop    ds            ;restore old ds and
  640.     ret                ;return
  641.  
  642.  
  643. no_buffers_left:
  644.     pr_ch_al    'c'
  645.     mov    dh,NO_SPACE
  646.     cli    ;block interrupts before we exit
  647.     stc            ;signal its an error - no more buffers
  648.     ret
  649.  
  650.     public    set_address
  651. set_address:
  652. ;set the address of the interface.
  653. ;enter with es:di -> place to get the address, cx = size of address buffer.
  654. ;exit with nc, cx = actual size of address, or cy if buffer not big enough.
  655.     assume    ds:nothing
  656.     clc
  657.     ret
  658.  
  659.  
  660. rcv_mode_3:
  661. ;receive mode 3 is the only one we support, so we don't have to do anything.
  662.     ret
  663.  
  664.  
  665.     public    set_multicast_list
  666. set_multicast_list:
  667. ;enter with ds:si ->list of multicast addresses, ax = number of addresses,
  668. ;  cx = number of bytes.
  669. ;return nc if we set all of them, or cy,dh=error if we didn't.
  670.     mov    dh,NO_MULTICAST
  671.     stc
  672.     ret
  673.  
  674.  
  675.     public    terminate
  676. terminate:
  677.     ret
  678.  
  679.     public    reset_interface
  680. reset_interface:
  681. ;reset the interface.
  682.     assume    ds:code
  683.     ret
  684.  
  685.  
  686. ;called    when we    want to determine what to do with a received packet.
  687. ;enter with cx = packet length, es:di -> packet type, dl = packet class.
  688.     extrn    recv_find: near
  689.  
  690. ;called after we have copied the packet into the buffer.
  691. ;enter with ds:si ->the packet, cx = length of the packet.
  692.     extrn    recv_copy: near
  693.  
  694. ;call this routine to schedule a subroutine that gets run after the
  695. ;recv_isr.  This is done by stuffing routine's address in place
  696. ;of the recv_isr iret's address.  This routine should push the flags when it
  697. ;is entered, and should jump to recv_exiting_exit to leave.
  698. ;enter with ax = address of routine to run.
  699.     extrn    schedule_exiting: near
  700.  
  701. ;recv_exiting jumps here to exit, after pushing the flags.
  702.     extrn    recv_exiting_exit: near
  703.  
  704.     extrn    count_in_err: near
  705.     extrn    count_out_err: near
  706.  
  707.     public    recv
  708. recv:
  709. ;called from the recv isr.  All registers have been saved, and ds=cs.
  710. ;Upon exit, the interrupt will be acknowledged.
  711.     assume    ds:code
  712.     mov    ax,offset recv_exiting    ;schedule recv_exiting to be called
  713.     call    schedule_exiting    ;  on exit.
  714. recv_2:
  715.     in_chip_reg        board_w_intreg,0    ; get interrupt source
  716.  
  717.     test    al,intreg_hdlc0        ;check if HDLC0
  718.     jne    not_hdlc0
  719.  
  720.     jmp    which_reg        ;Jump and check the chip
  721.  
  722. not_hdlc0:
  723.     pr_ch_al    '+'
  724.     ret            ;Not this chip so give up
  725.  
  726. which_reg:
  727.     in_chip_reg        board_w_hdlc0,hdlc_br_intflag
  728.     mov    hdlc0_data.copy_intflag,al    ;save the interrupt flags
  729. ;
  730. ;    We now analyse for the different interrupts that
  731. ;    may be present. We first make some tests for styles
  732. ;    of interrupts so we dont need to check everything
  733. ;    each time.
  734. ;
  735.     test    hdlc0_data.copy_intflag,hdlc_intflag_eopd or hdlc_intflag_fa or hdlc_intflag_rx1519 or hdlc_intflag_rxoflw
  736.     je    test_tint    ;No receive style interrupts so jump
  737.  
  738. ; There is a receive event
  739. ;
  740. ;    We recognise 8 receive events.
  741. ;    1/.    RX1519
  742. ;    2/.    RX1519 + RXOFLW
  743. ;    3/.    EOPD
  744. ;    4/.    EOPD+RX1519
  745. ;    5/.    EOPD + RX1519 + RXOFLW
  746. ;    6/.    FA + EOPD
  747. ;    7/.    FA + EOPD + RX1519
  748. ;    8/.    FA + EOPD + RX1519 + RXOFLW
  749. ;    We believe that other (potential) RX events cannot
  750. ;    occur. 
  751. ;    We recognise only three (major) states for the RX
  752. ;    protocol engine.
  753. ;    1/.    SKIPPING for the start of a packet; all data
  754. ;        is essentially ignored in this state. No
  755. ;        receive buffer will have been allocated.
  756. ;        We are in this state between packets or perhaps
  757. ;        because we have just run out of buffers!
  758. ;        See also state 3 below.
  759. ;    2/.    BUILDING a packet. Generally speaking,
  760. ;        providing we have enough room, 'packet' bytes
  761. ;        are just added into the buffer, 'good last' bytes
  762. ;        terminating the building of a packet and provoke
  763. ;        its delivery to the upper layer. Other data such
  764. ;        as 'bad last' or 'first' bytes cause the packet
  765. ;        being built to be discarded and the engine to
  766. ;        move to SKIPPING state. A first byte implies
  767. ;        a frame abort has been received of course.
  768. ;    3/.    It is also possible to be SKIPPING&BUILDING !
  769. ;        This occurs after we have read data that
  770. ;        would have moved us to BUILDING state but
  771. ;        we could not get buffer space. We need this
  772. ;        to properly detect frame aborts (see below).
  773. ;
  774. ;    EVENT PROCESSING in a little more detail.
  775. ;
  776. ;    1/. RX1519
  777. ;    We are required to clear 14 bytes from the fifo.
  778. ;    It is possible to show that in pathological
  779. ;    circumstances bytes other than packet bytes can
  780. ;    be in the FIFO!
  781. ;
  782. ;    2/.    RX1519 + RXOFLW
  783. ;    Regardless of state, we read 19 bytes from the FIFO.
  784. ;    We do this as we do not want to accidently
  785. ;    discard the front of a following packet.
  786. ;
  787. ;    3/.    EOPD
  788. ;    We process bytes up to a bad/good last byte.
  789. ;    We then deliver or discard the packet.
  790. ;    Clearly should not process more than 19 and
  791. ;    if RX1519 set it would be surprising if we
  792. ;    processed more than 14!
  793. ;
  794. ;    4/.    EOPD + RX1519
  795. ;    We are required to clear 14 bytes from the fifo.
  796. ;    Process as in 3/. above but make sure we clear
  797. ;    at LEAST 14 bytes. We might read more than 15
  798. ;    if for instance the EOPD occurred as the 16 byte
  799. ;    which had arrived while we were responding to
  800. ;    the event which interrupted us which was a 'packet'
  801. ;    byte in number 15. It is also possible that the 'last'
  802. ;    byte might be number 14 but a 'first' byte also arrived
  803. ;    in 15 creating the RX1519 to occur as well.
  804. ;
  805. ;    5/.    EOPD + RX1519 + RXOFLW
  806. ;    The RXOFLW implies we have missed stuff and some
  807. ;    data failed to get into the end of the FIFO. The
  808. ;    RX FIFO is supposed to enter a FLAG search mode after
  809. ;    overflowing. Thus is we process as in 3/. but EMPTY
  810. ;    the whole buffer(i.e. read 19 bytes)., 
  811. ;
  812. ;    6,7,8/.    I.E. any FA condition.
  813. ;    We will read upto 19 bytes of data. It would
  814. ;    be surprising if we read more than 14 unless RX1519
  815. ;    was also set. We will end when we discover a Frame
  816. ;    Abort condition. This is implied by a first byte
  817. ;    when building but ALSO by a first byte if skipping
  818. ;    and we have already seen a first byte!
  819. ;
  820. ;
  821. ;    Now set up some values. The maximum and minimum
  822. ;    count values, the current number read
  823. ;    and we clear the stop_status_mask.
  824.  
  825. ;    mov    minimum_read,1    ;often increased below
  826. ;    mov    maximum_read,14    ;typically we end before this
  827. ;    mov    stop_status_mask,0    ;clear the stop status mask
  828. ;
  829. ;test_fa:
  830. ;    test    hdlc0_data.copy_intflag,hdlc_intflag_fa
  831. ;    je    test_eopd
  832.     ; We have an FA so change stop_status_mask
  833.     ; and change the maximum read to 19 (?)
  834. ;    mov    stop_status_mask,mask_k_fabort
  835. ;    mov    maximum_read,19    ;typically we end before this
  836. ;    jmp    test_rxoflw    ;can avoid the eopd check
  837. ;
  838. ;test_eopd:
  839. ;    test    hdlc0_data.copy_intflag,hdlc_intflag_eopd
  840. ;    je    test_rxoflw
  841. ;    ; Its eopd so update stop_status_mask
  842. ;    ; and change the maximum read to 19 (?)
  843. ;    mov    stop_status_mask,mask_k_good or mask_k_bad
  844. ;    mov    maximum_read,19    ;typically we end before this
  845. ;
  846. ;test_rxoflw:
  847. ;    test    hdlc0_data.copy_intflag,hdlc_intflag_rxoflw
  848. ;    je    test_rx1519
  849. ;    ; Its Overflow so adjust minimum read number
  850. ;    ; and change the maximum read to 19 (?)
  851. ;    mov    minimum_read,19
  852. ;    mov    maximum_read,19    ;typically we end before this
  853. ;    jmp    test_rx_end    ;can avoid the rx1519 check
  854. ;
  855. ;test_rx1519:
  856. ;    test    hdlc0_data.copy_intflag,hdlc_intflag_rx1519
  857. ;    je    test_rx_end
  858. ;    ; Its Rx1519 so adjust the minimum read number
  859. ;    mov    minimum_read,14
  860. ;
  861. test_rx_end:
  862. ;
  863. ;WE DONT CARE WHAT CAUSED THE INTERRUPT NOW!
  864. ;
  865.     ; Now we call the routine to process the RX fifo having
  866.     ; hopefully set up all the correct conditions.
  867.  
  868.     call    rint_process
  869.  
  870. test_tint:
  871.     mov    al,hdlc0_data.copy_intflag
  872.     and    al,hdlc0_data.copy_intenable ; ignore any not expected
  873.     mov    hdlc0_data.copy_intflag,al
  874.  
  875.     test    hdlc0_data.copy_intflag,hdlc_intflag_txdone or hdlc_intflag_tx419 or hdlc_intflag_txurun
  876.     je    test_ga    ;No transmit style interrupts so jump
  877.  
  878. ; Its some sort of transmit event
  879.  
  880.     test    hdlc0_data.copy_intflag,hdlc_intflag_txurun
  881.     je    test_txdone
  882.     call    tint_txurun; its an underrun event
  883. ;    Now need to avoid the txdone and tx419 code etc ....
  884.     jmp    test_ga
  885.  
  886. test_txdone:
  887.     test    hdlc0_data.copy_intflag,hdlc_intflag_txdone
  888.     je    test_tx419
  889.     call    tint_txdone; its packet trans. complete event
  890.     jmp test_ga            ; NOTE tx419 will always be set
  891.         ;when txdone is set! As we have processed
  892.         ;the outgoing packet we must now NOT go
  893.         ;through the tx419 code as well! IMPORTANT!
  894.  
  895. test_tx419:
  896.     test    hdlc0_data.copy_intflag,hdlc_intflag_tx419
  897.     je    test_ga
  898.     call    tint_tx419; its a tx fifo low event
  899.  
  900. ; and carry on...
  901.  
  902. test_ga:
  903.     test    hdlc0_data.copy_intflag,hdlc_intflag_ga
  904.     je    int_fin
  905.  
  906. ;    Its a Go-ahead .. We should not get these..
  907.  
  908.     pr_ch_al    '-'
  909.  
  910. int_fin:
  911.  
  912. ;    Now we have finished.. Just output H so we can check
  913.  
  914.     ret
  915.  
  916. ;
  917. ;Process 8952 Receive interrupts
  918. ;
  919.  
  920. ;    Process all RX FIFO data
  921.  
  922. rint_process:    
  923. ;    pr_ch_al    'A'
  924.  
  925. ;    mov    number_read,0    ;none so far...
  926. ;    mov    rint_status_mask,0    ;clear the rint status mask
  927.  
  928.     movseg    es,ds
  929.  
  930. rint_loop:
  931. ;    NEED FIXES IN HERE
  932. ;    mov    al,number_read
  933. ;    cmp    maximum_read,al    ;check if data still due
  934. ;    jg    rint_some_due    ;yes there is
  935. ;    pr_ch_al    'B'
  936. ;    ret                ;no we have finished
  937.  
  938. ;rint_some_due:
  939.  
  940.     ;get fifo status and build into a mask
  941.     ;must first check that there is still some data left..
  942.     ; NOTE it is important that we dont get here less than
  943.     ; one microsecond after we last removed data.
  944.  
  945.     in_chip_reg        board_w_hdlc0,hdlc_br_fifostatus
  946.     test    al,hdlc_fifostatus_RXFIFO
  947.     jne    rint_fifo_not_empty
  948.     ret                    ; we have now emptied the RX FIFO
  949.                         ; so we return...
  950. rint_fifo_not_empty:        ;still some data so analyze...
  951.     mov    cl,6        ;number of bits to shift
  952.     and    al,hdlc_fifostatus_RXBYTE ;get RX byte status
  953.     shr    al,cl        ;shift to lower two bits
  954.     mov    cl,al        ;transfer to cl
  955.     mov    al,00000001b    ;set low bit in al
  956.     shl    al,cl            ;and shift to correct bit for mask
  957.     mov    byte_status_mask,al    ;save byte status mask
  958. ;    or    rint_status_mask,al    ;save rint segment status mask
  959.  
  960. ;
  961. ;    Now check our state
  962. ;
  963.     test    hdlc0_data.rxisr_w_state,state_k_skipping
  964.     jz    rint_building    ;must be building alone
  965.     jmp    rint_skipping    ;skipping or skipping&building
  966.  
  967. ;
  968. ;    Definitely building a packet
  969. ;
  970. rint_building:
  971.  
  972.     test    byte_status_mask,mask_k_good;good last byte ?        
  973.     jnz    rint_build_good_last            ;deal with good last byte
  974.  
  975.     test    byte_status_mask,mask_k_bad;bad last byte ?        
  976.     jnz    rint_build_bad_last            ;deal with bad last byte
  977.  
  978.     test    byte_status_mask,mask_k_first;first byte ?        
  979.     jnz    rint_build_first            ;deal with first byte
  980.  
  981. ;
  982. ;    must be packet byte
  983. ;
  984.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  985.     mov    di,hdlc0_data.rxisr_w_byte ;get ptr to next byte
  986.     stosb            ;store char into buffer
  987.     mov    hdlc0_data.rxisr_w_byte,di ;save ptr to next byte
  988.     
  989.     inc    hdlc0_data.rxisr_w_count            ;count for all isr calls
  990. ;    inc    number_read            ;count for this isr
  991.  
  992.     jmp    rint_end
  993.  
  994. rint_build_good_last:
  995. ;
  996. ;    good last byte coming, get it, then close
  997. ;    the packet and assign it to queue ownership etc.
  998. ;    then bump the pointers
  999. ;
  1000. ;    pr_ch_al    'C'
  1001.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1002.     mov    di,hdlc0_data.rxisr_w_byte ;get ptr to next byte
  1003.     stosb            ;store char into buffer
  1004.     mov    hdlc0_data.rxisr_w_byte,di ;save ptr to next byte
  1005.     inc    hdlc0_data.rxisr_w_count            ;count for all isr calls
  1006. ;    inc    number_read            ;count for this isr
  1007.  
  1008.     mov    bx,hdlc0_data.rxisr_w_pkt    ;get pointer to buffer
  1009.  
  1010.     mov    ax,hdlc0_data.rxisr_w_count ;save count in buffer
  1011.  
  1012.     mov    [bx].buff_w_size,ax ;via ax
  1013.  
  1014.     mov    [bx].buff_w_owner,owner_k_queue    ;mark in q
  1015.     mov    bx,[bx].buff_w_next    ;get pointer to next
  1016.     mov    hdlc0_data.rxq_w_back,bx    ;and save as back of queue
  1017. ;
  1018. ;    and change state
  1019. ;
  1020.     mov    hdlc0_data.rxisr_w_state,state_k_skipping
  1021.  
  1022.     jmp    rint_end
  1023.  
  1024. rint_build_bad_last:
  1025.  
  1026. ;
  1027. ;    Now deal with bad FCS, read the bad byte and then
  1028. ;    then discard the packet we have got so far.
  1029. ;
  1030.     pr_ch_al    'D'
  1031.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1032.                 ;get char but ignore
  1033. ;    inc    number_read            ;count for this isr
  1034.     mov    bx,hdlc0_data.rxisr_w_pkt    ;get ptr to buffer
  1035.     call    rint_reset    ;release the buffer etc
  1036. ;
  1037. ;    and change state
  1038. ;
  1039.     mov    hdlc0_data.rxisr_w_state,state_k_skipping
  1040.     jmp rint_end
  1041.  
  1042. rint_build_first:
  1043. ;
  1044. ;    Now deal with first byte, this must be a frame abort!
  1045. ;    DONT read the byte, leave it there for next iteration
  1046. ;    to use as part of the next packet.
  1047. ;    Discard the packet we have got so far.
  1048. ;
  1049.     pr_ch_al    'E'
  1050.     mov    bx,hdlc0_data.rxisr_w_pkt    ;get ptr to buffer
  1051.     call    rint_reset    ;release the buffer etc
  1052. ;
  1053. ;    Record the Frame Abort in the rint_status_mask
  1054. ;
  1055. ;    or    rint_status_mask,mask_k_fabort
  1056. ;
  1057. ;    and change state
  1058. ;
  1059.     mov    hdlc0_data.rxisr_w_state,state_k_skipping
  1060.     jmp rint_end
  1061.  
  1062. rint_skipping:
  1063. ;
  1064. ;    If we are here then we must be in between packets.
  1065. ;    It is possible that we may have run out of buffers
  1066. ;    so we may be actually discarding data that would
  1067. ;    otherwise have been good. If this second situation
  1068. ;    exists then both the building and skipping bits
  1069. ;    are set in the state mask.
  1070. ;
  1071.  
  1072.     test    byte_status_mask,mask_k_good;good last byte ?        
  1073.     jnz    rint_skip_good_last            ;deal with good last byte
  1074.  
  1075.     test    byte_status_mask,mask_k_bad;bad last byte ?        
  1076.     jnz    rint_skip_bad_last            ;deal with bad last byte
  1077.  
  1078.     test    byte_status_mask,mask_k_first;first byte ?        
  1079.     jnz    rint_skip_first            ;deal with first byte
  1080.  
  1081. ;
  1082. ;    must be packet byte
  1083. ;
  1084.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1085.                 ;get char but ignore
  1086. ;    inc    number_read            ;count for this isr
  1087. ;
  1088. ;    Well we are certainly skipping past bytes now.
  1089. ;
  1090.     mov    hdlc0_data.rxisr_w_state,state_k_skipping or state_k_building
  1091.  
  1092.     jmp    rint_end
  1093.  
  1094. rint_skip_good_last:
  1095. ;
  1096. ;    good last byte coming, get it, and ignore
  1097. ;
  1098.     pr_ch_al    'F'
  1099.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1100.                 ;get char but ignore
  1101. ;    inc    number_read            ;count for this isr
  1102.  
  1103. ;
  1104. ;    change state (might have been skipping and building)
  1105. ;
  1106.     mov    hdlc0_data.rxisr_w_state,state_k_skipping
  1107.  
  1108.     jmp    rint_end
  1109.  
  1110. rint_skip_bad_last:
  1111.  
  1112. ;
  1113. ;    Now deal with bad FCS, read the bad byte and ignore
  1114. ;
  1115.     pr_ch_al    'G'
  1116.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1117.                 ;get char but ignore
  1118. ;    inc    number_read            ;count for this isr
  1119. ;
  1120. ;    change state (might have been skipping and building)
  1121. ;
  1122.     mov    hdlc0_data.rxisr_w_state,state_k_skipping
  1123.     jmp rint_end
  1124.  
  1125. rint_skip_first:
  1126.  
  1127. ;
  1128. ;    Now deal with first byte, this must be the start
  1129. ;    of the next packet.
  1130. ;
  1131.     test    hdlc0_data.rxisr_w_state,state_k_building
  1132.     jnz    rint_skip_build    ;skipping&building
  1133. ;
  1134. ;    As we are here we are just skipping at the moment.
  1135. ;    As we have found a first byte, we now try to
  1136. ;    get a buffer in which to build the new packet.
  1137. ;
  1138.     call    rint_get_buffer
  1139.     jnc    rint_skip_first_got_buffer
  1140. ;
  1141. ;    We failed to get buffer. We thus must discard
  1142. ;    the incoming data, count it and move to the
  1143. ;    skipping&building state.
  1144. ;
  1145.     pr_ch_al    'H'
  1146.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1147.                 ;get char but ignore
  1148. ;    inc    number_read            ;count for this isr
  1149. ;
  1150. ;    and change state
  1151. ;
  1152.     mov    hdlc0_data.rxisr_w_state,state_k_skipping or state_k_building
  1153.     jmp rint_end
  1154.  
  1155. rint_skip_first_got_buffer:
  1156. ;    pr_ch_al    'I'
  1157.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1158.     mov    di,hdlc0_data.rxisr_w_byte ;get ptr to next byte
  1159.     stosb            ;store char into buffer
  1160.     mov    hdlc0_data.rxisr_w_byte,di ;save ptr to next byte
  1161.     
  1162.     inc    hdlc0_data.rxisr_w_count            ;count for all isr calls
  1163. ;    inc    number_read            ;count for this isr
  1164. ;
  1165. ;    and change state
  1166. ;
  1167.     mov    hdlc0_data.rxisr_w_state,state_k_building
  1168.     jmp    rint_end
  1169.  
  1170. rint_skip_build:
  1171. ;
  1172. ;    We are skipping and building. I.e. we are
  1173. ;    discarding data that probably would have been
  1174. ;    good but we had no buffers available.
  1175. ;    Thus if we find a first byte this must be a frame
  1176. ;    abort. Deal with it as such, leaving the byte in
  1177. ;    the FIFO to be picked up on the next cycle.
  1178. ;
  1179. ;    Record the Frame Abort in the rint_status_mask
  1180. ;
  1181.     pr_ch_al    'J'
  1182. ;    or    rint_status_mask,mask_k_fabort
  1183. ;
  1184. ;    and change state
  1185. ;
  1186.     mov    hdlc0_data.rxisr_w_state,state_k_skipping
  1187.  
  1188.     jmp rint_end
  1189.  
  1190. rint_end:
  1191. ;
  1192. ;    Now is the time to tidy up at the end of
  1193. ;    the rint loop. Several things to check. For instance,
  1194. ;    if we are still building and not skipping then
  1195. ;    if the packet is already full we have a problem.
  1196. ;    The best policy must be to discard and move
  1197. ;    to skipping&building state.
  1198. ;
  1199. ;    We must also check if we need to stop iterating.
  1200. ;    If we have not yet read the minimum_read number
  1201. ;    of bytes we must go again. If we have, then
  1202. ;    unless we have got a rint_status_mask that has 
  1203. ;    at least one bit in common with our stop_status_mask
  1204. ;    we must also loop again.
  1205.  
  1206.     test    hdlc0_data.rxisr_w_state,state_k_skipping
  1207.     jnz    rint_info_size_ok    ;dont care...
  1208.  
  1209.     cmp    hdlc0_data.rxisr_w_count,info_k_size    ;check if room for more info
  1210.     jl    rint_info_size_ok    ;and branch if ok
  1211. ;
  1212. ;    TOO much data in this packet, the next byte
  1213. ;    even if it were a last byte would overfill
  1214. ;    the info area. We must therefore discard the packet
  1215. ;    and move to the skipping&building state.
  1216.     pr_ch_al    'K'
  1217.     mov    bx,hdlc0_data.rxisr_w_pkt    ;get ptr to buffer
  1218.     call    rint_reset    ;release the buffer etc
  1219. ;
  1220. ;    and change state
  1221. ;
  1222.     mov    hdlc0_data.rxisr_w_state,state_k_skipping or state_k_building
  1223.  
  1224. rint_info_size_ok:
  1225. ;    mov    al,number_read
  1226. ;    cmp    minimum_read,al    ;have we read enough?
  1227. ;    jle    rint_enough            ;yes
  1228.     jmp    rint_loop                ; no go read some more..
  1229.  
  1230. ;rint_enough:
  1231. ;    mov    al,stop_status_mask
  1232. ;    test    rint_status_mask,al    ;stop state?
  1233. ;    jnz    rint_stop_state        ;yes
  1234. ;    jmp    rint_loop                ; no go read some more..
  1235.  
  1236. ;rint_stop_state:
  1237. ;
  1238. ;    Well that seems to be it for this call to the RX
  1239. ;    interrupt service routine so bye bye...
  1240.  
  1241. ;    ret
  1242.     
  1243. ;
  1244. ;    Routine to get a buffer (or not)
  1245. ;
  1246.  
  1247. rint_get_buffer:
  1248. ;    pr_ch_al    'L'
  1249.  
  1250.     mov    bx,hdlc0_data.rxq_w_back    ;get back of queue
  1251.     cmp    [bx].buff_w_owner,owner_k_empty    ;is it empty?
  1252.     jne    cant_get_buffer
  1253.  
  1254.     call rint_grab
  1255.     clc        ;all o.k.
  1256.     ret
  1257. cant_get_buffer:
  1258.     pr_ch_al    'M'
  1259.     stc        ;signal error (well at least no buffers left)
  1260.     ret
  1261.  
  1262. rint_grab:
  1263.     or    bx,bx
  1264.     jz    rint_grab_problem
  1265.     mov    [bx].buff_w_owner,owner_k_isr    ;mark inuse by isr
  1266.     mov    hdlc0_data.rxisr_w_pkt,bx    ;save for isr to use next
  1267.     lea    ax,[bx].buff_info    ;get address of new info area
  1268.     mov    hdlc0_data.rxisr_w_byte,ax    ;save for isr
  1269.     mov    hdlc0_data.rxisr_w_count,0    ;and clear count
  1270. ;    Now set the state to mark as BUILDING
  1271.     mov    hdlc0_data.rxisr_w_state,state_k_building
  1272.     clc
  1273.     ret
  1274. rint_grab_problem:
  1275.     pr_ch_al    'N'
  1276.     stc
  1277.     ret
  1278.  
  1279. rint_reset:
  1280.     or    bx,bx
  1281.     jz    rint_reset_problem
  1282.     mov    [bx].buff_w_owner,owner_k_empty    ;mark empty
  1283.     clc
  1284.     ret
  1285. rint_reset_problem:
  1286.     pr_ch_al    'O'
  1287.     stc
  1288.     ret
  1289.  
  1290. ; --------------------------------------------------------------
  1291. ;
  1292. ;  recv_exiting
  1293. ;
  1294. recv_exiting:
  1295.     assume    ds:nothing
  1296.     pushf
  1297.     push    ax
  1298.     push    bx
  1299.     mov    bx,hdlc0_data.rxq_w_front        ;get pointer to next buffer
  1300.     cmp    code:[bx].buff_w_owner,owner_k_queue    ;belongs to q?
  1301.     jne    recv_exiting_done    ; no - skip to end
  1302.     push    cx
  1303.     push    dx
  1304.     push    ds
  1305.     push    es
  1306.     push    bp
  1307.     push    di
  1308.     push    si
  1309.     movseg    ds,cs
  1310.     assume    ds:code
  1311.     cmp    hdlc0_data.rxupcall_w_state,upcall_k_idle    ;is receive frame already active?
  1312.     jne    already_active        ;frame will be caught so jump
  1313.     mov    hdlc0_data.rxupcall_w_state,upcall_k_active    ;else mark recv_frame starting
  1314.     sti                ; enable interrupts
  1315.  
  1316.     call    recv_frame
  1317.  
  1318.     cli
  1319. already_active:
  1320.     pop    si
  1321.     pop    di
  1322.     pop    bp
  1323.     pop    es
  1324.     pop    ds
  1325.     pop    dx
  1326.     pop    cx
  1327. recv_exiting_done:
  1328.     pop    bx
  1329.     pop    ax
  1330.     jmp    recv_exiting_exit
  1331.  
  1332.  
  1333. ; --------------------------------------------------------------
  1334. ;
  1335. ;  recv_frame
  1336. ;
  1337.   ifdef debug
  1338.     public recv_frame
  1339.   endif
  1340. recv_frame:
  1341. ;    pr_ch_al    'P'
  1342.  
  1343.     mov    bx,hdlc0_data.rxq_w_front        ;get pointer to next buffer
  1344.  
  1345. recv_frame_2:
  1346.     lea    si,[bx].buff_info        ;point to data
  1347.     mov    cx,[bx].buff_w_size    ;get its size
  1348.     jcxz    recv_frame_3        ;count zero? yes,just free frame.
  1349. ;we don't need to set the type because none are defined for our HDLC encoding.
  1350.     push    si            ;save si in case we reject it.
  1351.     push    bx
  1352.     mov    di,0            ;but we avoid any segment end bullshit.
  1353.     mov    dl,cs:driver_class
  1354.     call    recv_find        ;look up our type.
  1355.     pop    bx
  1356.     pop    si
  1357.  
  1358.     mov    ax,es            ;is this pointer null?
  1359.     or    ax,di
  1360.     je    recv_frame_3        ;yes - just free the frame.
  1361. ;    pr_ch_al    'Q'
  1362.     push    cx
  1363.     push    es            ;remember where the buffer pointer is.
  1364.     push    di
  1365.  
  1366.     rep    movsb    ;and copy our packet into users buffer
  1367.  
  1368.     pop    si            ;now give the frame to the client.
  1369.     pop    ds
  1370.     pop    cx
  1371. ;    pr_ch_al    'R'
  1372.     assume    ds:nothing
  1373.  
  1374.     call    recv_copy
  1375.     movseg    ds,cs
  1376.     pr_ch_al    'S'
  1377.     assume    ds:code
  1378.  
  1379. recv_frame_3:
  1380.     mov    [bx].buff_w_owner,owner_k_empty    ;free the buffer
  1381.     mov    bx,[bx].buff_w_next        ;get pointer to next
  1382.     mov    hdlc0_data.rxq_w_front,bx        ;adjust front of q
  1383.  
  1384.     cmp    [bx].buff_w_owner,owner_k_queue    ;belongs to q?
  1385.     je    recv_frame_2        ; yes so process this one.
  1386.     mov    hdlc0_data.rxupcall_w_state,upcall_k_idle    ;else mark recv_frame as inactive
  1387. ;    pr_ch_al    'T'
  1388.     ret
  1389.  
  1390. ;Handle 8952 transmitter interrupts
  1391.  
  1392. ; --------------------------------------------------------------
  1393.  
  1394. tint_txurun:
  1395.     pr_ch_al    'd'
  1396.     mov    bx,hdlc0_data.txisr_w_pkt    ;point to the packet buffer
  1397.     call    tint_reset    ;reset pointers etc...
  1398.     ret
  1399.  
  1400.  
  1401. tint_tx419:
  1402. ;
  1403. ; - for MT8952B fifo stuff up to 15 chars at a time
  1404. ;
  1405. ;    NOW NEED TO POINT DX at TX FIFO
  1406. ;
  1407.     mov    dx,board_w_hdlc0        ;make dx point at transmit fifo
  1408.     add    dx,hdlc_bw_transmit
  1409.     mov    cx,15                   ;fifo fill-loop counter
  1410.     mov    bx,hdlc0_data.txisr_w_count    ;get count of bytes left
  1411.     mov    si,hdlc0_data.txisr_w_byte    ;get pointer to next byte
  1412. tint_next:
  1413.     lodsb                ;fetch next char
  1414.     dec    bx            ;reduce count of remaining bytes
  1415.     jne    not_send_last
  1416.     push    dx                ;save dx
  1417.     mov    dx,board_w_hdlc0
  1418.     add    dx,hdlc_b_control
  1419.     push    ax
  1420.     in    al,dx                ;get current hdlc control reg
  1421.     or    al,hdlc_control_eop    ;mark as end of packet
  1422.     out    dx,al                ;and tell the 8952
  1423.     pop    ax                ; restore al
  1424.     pop    dx                ;and dx
  1425.  
  1426. not_send_last:
  1427.     out    dx,al            ;output char
  1428.     or    bx,bx        ;any more chars to output
  1429.     je    tint_no_more        ;none...
  1430.     loop    tint_next        ;loop while fifo not full
  1431. ;
  1432. ;    Still some more so select TXURUN and TX419 ints enabled
  1433. ;
  1434.     pr_ch_al    'e'
  1435.     mov    dx,board_w_hdlc0
  1436.     add    dx,hdlc_bw_intenable
  1437. ;    in    al,dx                ;get current hdlc intenable
  1438.     mov    al,hdlc0_data.copy_intenable
  1439. ;
  1440. ;    switch off txdone interrupt and enable tx419 and txurun
  1441. ;
  1442.     and    al,not hdlc_intenable_txdone
  1443.     or    al,hdlc_intenable_tx419 or hdlc_intenable_txurun
  1444.     out    dx,al                ;and tell the 8952
  1445.     mov    hdlc0_data.copy_intenable,al        ;and save it
  1446.  
  1447.     mov    hdlc0_data.txisr_w_count,bx    ;save count of bytes left
  1448.     mov    hdlc0_data.txisr_w_byte,si    ;save pointer to next byte
  1449.     clc        ;clear carry, all ok
  1450.     ret        ;and exit
  1451.  
  1452. tint_no_more:
  1453. ;
  1454. ;    No more so select TXDONE and TXURUN ints enabled only
  1455. ;
  1456.     pr_ch_al    'f'
  1457.     mov    dx,board_w_hdlc0
  1458.     add    dx,hdlc_bw_intenable
  1459. ;    in    al,dx                ;get current hdlc intenable
  1460.     mov    al,hdlc0_data.copy_intenable
  1461. ;
  1462. ;    switch off tx419 interrupt and enable txurun and txdone 
  1463. ;
  1464.     and    al,not hdlc_intenable_tx419
  1465.     or    al,hdlc_intenable_txdone or hdlc_intenable_txurun
  1466.     out    dx,al                ;and tell the 8952
  1467.     mov    hdlc0_data.copy_intenable,al        ;and save it
  1468.  
  1469.     mov    hdlc0_data.txisr_w_count,bx    ;save count of bytes left
  1470.     mov    hdlc0_data.txisr_w_byte,si    ;save pointer to next byte
  1471.     clc        ;clear carry if all ok
  1472.     ret        ;and exit
  1473.  
  1474. ;No more characters to transmit -- disable transmit interrupts.
  1475.  
  1476. tint_txdone:
  1477. ;    pr_ch_al    'g'
  1478.     mov    bx,hdlc0_data.txisr_w_pkt    ;get pointer to isrs pkt
  1479.     or    bx,bx                ;check if pkt pointer is 0
  1480.     je    tint_skip
  1481.     mov    [bx].buff_w_owner,owner_k_empty;set owned by empty
  1482. tint_skip:
  1483.     call    tint_new    ;try to move to next buffer
  1484.     jc    tint_all_empty    ;if carry set then none left
  1485.     clc
  1486.     ret
  1487.  
  1488. tint_all_empty:
  1489. ;
  1490. ;    No more so set all tx ints off
  1491. ;
  1492. ;    pr_ch_al    'h'
  1493.     mov    dx,board_w_hdlc0
  1494.     add    dx,hdlc_bw_intenable
  1495. ;    in    al,dx                ;get current hdlc intenable
  1496.     mov    al,hdlc0_data.copy_intenable
  1497. ;
  1498. ;    switch off tx419, txurun and txdone 
  1499. ;
  1500.     and    al,not (hdlc_intenable_tx419 or hdlc_intenable_txdone or hdlc_intenable_txurun)
  1501.     out    dx,al                ;and tell the 8952
  1502.     mov    hdlc0_data.copy_intenable,al        ;and save it
  1503.  
  1504.     xor    ax,ax        ;clear ax
  1505.     mov    hdlc0_data.txisr_w_pkt,ax    ;save in pointer to buffer
  1506.     ret
  1507.  
  1508. ;
  1509. ;    Routine to get info for next packet from queue
  1510. ;
  1511. tint_new:
  1512.     mov    bx,hdlc0_data.txq_w_front    ;get pointer to front of queue
  1513.     cmp    [bx].buff_w_owner,owner_k_queue    ;belongs to q?
  1514.     jne    tint_no_buffers_in_queue
  1515. ;
  1516. ;    now bump the front of queue
  1517. ;
  1518.     pr_ch_al    'i'
  1519.     mov    ax,[bx].buff_w_next    ;point to buffer
  1520.     mov    hdlc0_data.txq_w_front,ax    ;adjust front of queue
  1521. ;
  1522.     call    tint_reset    ;and set the pointers etc.
  1523.     ret
  1524.  
  1525. tint_reset:
  1526.     or    bx,bx
  1527.     jz    tint_reset_problem
  1528.     mov    [bx].buff_w_owner,owner_k_isr;set owned by the isr
  1529.     mov    ax,[bx].buff_w_size    ;get size of data unit
  1530.     mov    hdlc0_data.txisr_w_count,ax    ;and save it for us
  1531.     mov    hdlc0_data.txisr_w_pkt,bx    ;save pointer to buffer
  1532.     lea    ax,[bx].buff_info    ;get address of data unit
  1533.     mov    hdlc0_data.txisr_w_byte,ax    ;and save for us
  1534.     call    tint_tx419        ;and pretend we had a tx419
  1535.     ret
  1536. tint_reset_problem:
  1537.     stc
  1538.     ret
  1539. tint_no_buffers_in_queue:
  1540.     pr_ch_al    'j'
  1541.     stc        ;set carry - could not do it
  1542.     ret
  1543.  
  1544. ;Set bit(s) in I/O port
  1545. setbit:
  1546. ;enter with dx = port, ah = bit to set.
  1547.     in    al,dx
  1548.     or    al,ah
  1549.     out    dx,al
  1550.     ret
  1551.  
  1552.  
  1553. ;Clear bit(s) in I/O port
  1554. clrbit:
  1555. ;enter with dx = port, ah = bit to set.
  1556.     in    al,dx
  1557.     not    al            ;perform an and-not using DeMorgan's.
  1558.     or    al,ah
  1559.     not    al
  1560.     out    dx,al
  1561.     ret
  1562.  
  1563. ;
  1564. ;    Now define some buffers for the rings.
  1565. ;    Do it statically now because its easier.
  1566. ;
  1567. ;    First the transmit ring
  1568. ;
  1569. t1_buff    buff    <offset t8_buff, offset t2_buff>
  1570. t2_buff    buff    <offset t1_buff, offset t3_buff>
  1571. t3_buff    buff    <offset t2_buff, offset t4_buff>
  1572. t4_buff    buff    <offset t3_buff, offset t5_buff>
  1573. t5_buff    buff    <offset t4_buff, offset t6_buff>
  1574. t6_buff    buff    <offset t5_buff, offset t7_buff>
  1575. t7_buff    buff    <offset t6_buff, offset t8_buff>
  1576. t8_buff    buff    <offset t7_buff, offset t1_buff>
  1577. ;
  1578. ;    Now the Receive ring
  1579. ;
  1580. r1_buff    buff    <offset r8_buff, offset r2_buff>
  1581. r2_buff    buff    <offset r1_buff, offset r3_buff>
  1582. r3_buff    buff    <offset r2_buff, offset r4_buff>
  1583. r4_buff    buff    <offset r3_buff, offset r5_buff>
  1584. r5_buff    buff    <offset r4_buff, offset r6_buff>
  1585. r6_buff    buff    <offset r5_buff, offset r7_buff>
  1586. r7_buff    buff    <offset r6_buff, offset r8_buff>
  1587. r8_buff    buff    <offset r7_buff, offset r1_buff>
  1588. ;
  1589. ;    include the serial trace output subroutines
  1590. ;
  1591.  
  1592.     include    popf.asm
  1593.     include    sersub.asm
  1594.  
  1595.     public    timer_isr
  1596. timer_isr:
  1597. ;if the first instruction is an iret, then the timer is not hooked
  1598.     iret
  1599.  
  1600. ;any code after this will not be kept after initialization. Buffers
  1601. ;used by the program, if any, are allocated from the memory between
  1602. ;end_resident and end_free_mem.
  1603.     public end_resident,end_free_mem
  1604. end_resident    label    byte
  1605. end_free_mem    label    byte
  1606.  
  1607.     public    usage_msg
  1608. usage_msg    db    "usage: EXPRESS <packet_int_no> [-n] [driver_class] [hardware_irq] ",CR,LF
  1609.         db    "   -n instructs card to be an NT",CR,LF
  1610.         db    "   The driver_class should be SLIP or a number.",CR,LF,'$'
  1611.  
  1612.     public    copyright_msg
  1613. copyright_msg    db    "Packet driver for MITEL EXPRESS CARD, version ",'0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,CR,LF
  1614.         db    "Portions Copyright 1988 Phil Karn",CR,LF
  1615.         db    "ISDN bits by Dave Price and Bob Gautier",CR,LF,'$'
  1616.  
  1617. class_name_ptr    dw    ?
  1618. class_name    db    "Interface class ",'$'
  1619. slip_name    db    "SLIP",CR,LF,'$'
  1620. int_no_name    db    "Interrupt number ",'$'
  1621. express_start    db    "starting to initial EXPRESS card",CR,LF,'$'
  1622. express_finish    db    "completed initialization of EXPRESS card",CR,LF,'$'
  1623.  
  1624.     extrn    set_recv_isr: near
  1625.  
  1626. ;enter with si -> argument string, di -> word to store.
  1627. ;if there is no number, don't change the number.
  1628.     extrn    get_number: near
  1629.  
  1630. ;enter with dx -> name of word, di -> dword to print.
  1631.     extrn    print_number: near
  1632.  
  1633. ;enter with si -> argument string.
  1634. ;skip spaces and tabs.  Exit with si -> first non-blank char.
  1635.     extrn    skip_blanks: near
  1636.  
  1637.  
  1638.     public    parse_args
  1639. parse_args:
  1640. ;exit with nc if all went well, cy otherwise.
  1641.     call    skip_blanks
  1642.     cmp    al,'-'            ;did they specify a switch?
  1643.     jne    not_switch
  1644. ;
  1645. ;    Only SUPPORT -n SWITCH ARGUMENT AT THE MOMENT
  1646. ;
  1647.     cmp    byte ptr [si+1],'n'    ;did they specify '-n'?
  1648.     je    got_NT_switch
  1649.     stc                ;no, must be an error.
  1650.     ret
  1651. got_NT_switch:
  1652.     mov    NT_switch,1
  1653.     add    si,2            ;skip past the switch's characters.
  1654.     jmp    parse_args        ;go parse more arguments.
  1655. not_switch:
  1656.     or    al,20h            ;convert to lower case (assuming letter).
  1657. parse_args_2:
  1658.     cmp    al,'s'
  1659.     jne    parse_args_3
  1660.     mov    driver_class,6        ;SLIP, from packet spec.
  1661.     mov    dx,offset slip_name
  1662.     jmp    short parse_args_1
  1663. parse_args_3:
  1664.     mov    di,offset driver_class
  1665.     call    get_number
  1666.     mov    class_name_ptr,0
  1667.     jmp    short parse_args_6
  1668. parse_args_1:
  1669.     mov    class_name_ptr,dx
  1670. parse_args_5:
  1671.     mov    al,[si]            ;skip to the next blank or CR.
  1672.     cmp    al,' '
  1673.     je    parse_args_6
  1674.     cmp    al,CR
  1675.     je    parse_args_6
  1676.     inc    si            ;skip the character.
  1677.     jmp    parse_args_5
  1678. parse_args_6:
  1679.     mov    di,offset int_no
  1680.     call    get_number
  1681. ;
  1682. ;    Might get number of buffer in TX queue here.
  1683. ;
  1684.     clc
  1685.     ret
  1686.  
  1687.  
  1688. ; --------------------------------------------------------------
  1689. ;
  1690. ;  etopen
  1691. ;
  1692.  
  1693.     public    etopen
  1694. etopen:
  1695.     pushf
  1696.     cli
  1697.  
  1698.     call    open    ; open the serial port for traces
  1699.  
  1700.     ;let user know we are about to initial
  1701.     ; the express card
  1702.  
  1703.     pr_ch_al    '$'
  1704. ;
  1705. ;Now set up the Mitel Express Card
  1706. ;
  1707. ;
  1708. ;    First the dphone - this controls timing as well
  1709. ;
  1710.     out_chip_reg_value    board_w_dphone,dphone_b_test,dphone_test_disable
  1711. ;
  1712. ;    Now the board timing via the dphone sense/drive port
  1713. ;
  1714.     out_chip_reg_value    board_w_dphone,dphone_b_sddir,dphone_sddir_allout
  1715.     cmp    NT_switch,1    ;has user selected NT operation
  1716.     jne    act_as_te        ;no so set as TE
  1717.     out_chip_reg_value    board_w_dphone,dphone_b_sddata,dphone_sddata_nt
  1718.     jmp    te_nt_set
  1719.  
  1720. act_as_te:
  1721.     out_chip_reg_value    board_w_dphone,dphone_b_sddata,dphone_sddata_te
  1722.  
  1723. te_nt_set:
  1724.  
  1725. ;
  1726. ;    Now set use of st-bus timeslots
  1727. ;
  1728.     out_chip_reg_value    board_w_dphone,dphone_b_time,<dphone_time_c or dphone_time_pcmb1>
  1729. ;
  1730. ;    Now stop the watchdog
  1731. ;
  1732.     out_chip_reg_value    board_w_dphone,dphone_b_wdog,0
  1733. ;
  1734. ;    Now set the tone values
  1735. ;
  1736.     out_chip_reg_value    board_w_dphone,dphone_b_tone1,dphone_tone_697
  1737.     out_chip_reg_value    board_w_dphone,dphone_b_tone2,dphone_tone_1209
  1738. ;
  1739. ;    Now set up the dsp
  1740. ;
  1741.     out_chip_reg_value    board_w_dphone,dphone_b_dsp,<dphone_dsp_cpcmen or dphone_dsp_dpcmen or dphone_dsp_dual>
  1742. ;
  1743. ;    Now set up the transducers
  1744. ;
  1745.     out_chip_reg_value    board_w_dphone,dphone_b_trans,<dphone_trans_side or dphone_trans_hsmic or dphone_trans_hsskr>
  1746. ;
  1747. ;    Finally the Receive gain control
  1748. ;
  1749.     out_chip_reg_value    board_w_dphone,dphone_b_rgain,dphone_rgain_rfg_m7
  1750. ;
  1751. ;    Second the snic
  1752. ;
  1753.     out_chip_reg_value    board_w_snic,snic_b_master,<snic_master_cstenable or snic_master_msdisable or snic_master_irqenable>
  1754.     out_chip_reg_value    board_w_snic,snic_b_stbus,snic_stbus_all
  1755. ;
  1756. ;    Now set up the hdlc controller
  1757. ;
  1758.     out_chip_reg_value    board_w_hdlc0,hdlc_b_time,hdlc_time_rst
  1759. ;
  1760. ;    NOTE you are required to clear reset TWICE
  1761. ;
  1762.     out_chip_reg_value    board_w_hdlc0,hdlc_b_time,<hdlc_time_ic or hdlc_time_brck or hdlc_time_c2bits8>
  1763.     out_chip_reg_value    board_w_hdlc0,hdlc_b_time,<hdlc_time_ic or hdlc_time_brck or hdlc_time_c2bits8>
  1764.  
  1765.     out_chip_reg_value    board_w_hdlc0,hdlc_b_control,<hdlc_control_rxen or hdlc_control_txen>
  1766.  
  1767.     out_chip_reg_value    board_w_hdlc0,hdlc_b_raddress,00
  1768.     out_chip_reg_value    board_w_hdlc0,hdlc_bw_wdog,00
  1769.  
  1770.     out_chip_reg_value    board_w_hdlc0,hdlc_bw_intenable,<hdlc_intenable_eopd or hdlc_intenable_fa or hdlc_intenable_rx1519 or hdlc_intenable_rxoflw>
  1771.     mov    hdlc0_data.copy_intenable,al        ;and save it
  1772.  
  1773. ;
  1774. ;    Now the DX; plug up the channels and send messages etc,
  1775. ;
  1776.  
  1777.     dx_source    snic_stream,snic_b2_channel,dphone_stream,dphone_b1_channel
  1778.     dx_source    dphone_stream,dphone_b1_channel,snic_stream,snic_b2_channel
  1779.  
  1780.     dx_source    snic_stream,snic_b1_channel,hdlc_stream,hdlc_b1_channel
  1781.     dx_source    hdlc_stream,hdlc_b1_channel,snic_stream,snic_b1_channel
  1782.  
  1783. ;
  1784. ;    MIGHT NEED TO CHANGE THE NEXT FOR NT OPERATION
  1785. ;
  1786.  
  1787.     dx_message    snic_stream,snic_c_channel,<<snic_c_ar or snic_c_clrdia>>
  1788.  
  1789.     ;let user know we have finished
  1790.     ; initializing the express card
  1791.  
  1792.     pr_ch_al    '%'
  1793.  
  1794. ;Set interrupt vector to EXPRESS handler
  1795.  
  1796.     call    set_recv_isr
  1797.  
  1798.     popf
  1799.     clc                ;indicate no errors.
  1800.     ret
  1801.  
  1802.  
  1803.     public    print_parameters
  1804. print_parameters:
  1805.     cmp    class_name_ptr,0
  1806.     je    echo_args_1
  1807.  
  1808.     mov    dx,offset class_name
  1809.     mov    ah,9
  1810.     int    21h
  1811.     mov    dx,class_name_ptr
  1812.     mov    ah,9
  1813.     int    21h
  1814.     jmp    short echo_args_2
  1815. echo_args_1:
  1816.     mov    di,offset driver_class
  1817.     mov    dx,offset class_name
  1818.     call    print_number
  1819. echo_args_2:
  1820.  
  1821.     mov    di,offset int_no
  1822.     mov    dx,offset int_no_name
  1823.     call    print_number
  1824.  
  1825.     ret
  1826.  
  1827. code    ends
  1828.  
  1829.     end
  1830.