LDRIVER.ASM
上传用户:sunrenlu
上传日期:2022-06-13
资源大小:1419k
文件大小:28k
源码类别:

操作系统开发

开发平台:

DOS

  1. page  65,132
  2. title DRIVER.ASM Multi I/O Board Driver for Flashlite 386Ex
  3. subttl Copyright JK microsystems 1998
  4. ;************************************************************************;
  5. ;*         *;
  6. ;* Copyright JK microsystems 1998 -  All Rights Reserved    *;
  7. ;* *;
  8. ;* This software is NOT shareware, freeware, or public domain. *;
  9. ;* It is the property of JK microsystems. *;
  10. ;* *;
  11. ;* Customers of JK microsystems may modify the source code *; 
  12. ;* and/or distribute the binary image of this software without  *;
  13. ;* additional costs provided it is run only on hardware  *;
  14. ;* manufactured by JK microsystems.  All other use is expressly  *;
  15. ;* prohibited. *;
  16. ;* *;
  17. ;* Update Log *;
  18. ;* *;
  19. ;* Version Date  Comments  Progammer *;
  20. ;* ------- -------  ------------------------------- ---------- *;
  21. ;* 1.0 10-20-98 First release    jds *;
  22. ;* 1.1     04-01-99 Fixed A/D chan 0 command byte  jds *;
  23. ;* 2.0 04-07-99 Fixed A/D for Rev C boards  jds *;
  24. ;* *;
  25. ;************************************************************************;
  26.         .model large
  27. .code
  28. ;-------------------------------------------------------------------------
  29. ;
  30. ; The following routines are the C and Quickbasic entry points for
  31. ;  the actual routines.  C entry points are prefaced with an under-
  32. ; score.  At the entry point, the arguments are moved around so that 
  33. ; a common routine can be called.  Also, a new stack is set up before 
  34. ; entry and the old stack is restored on exit.
  35. ;
  36. ; For information on the routines, see the _asm routine that is 
  37. ; called.
  38. ;
  39. public  _GetVersion
  40. _GetVersion  proc ; C routine
  41. push bp
  42. mov  bp,sp
  43.         mov     ax,[bp+6]
  44. call new_stack
  45. call GetVersion_asm
  46. call old_stack
  47. pop bp
  48. ret
  49. _GetVersion endp
  50. public  GetVersion ; Qbasic routine
  51. GetVersion proc
  52. push bp
  53. mov  bp,sp
  54. mov bx,ss:[bp+6]
  55. mov ax,[bx]
  56. call new_stack
  57. call GetVersion_asm
  58. call old_stack
  59. mov [bx],ax
  60. pop bp
  61. retf 2
  62. GetVersion endp
  63. public  _GetA2D
  64. _GetA2D  proc ; C routine
  65. push bp
  66. mov  bp,sp
  67.         mov     ax,[bp+6]
  68. call new_stack
  69. call GetA2D_asm
  70. call old_stack
  71. pop bp
  72. ret
  73. _GetA2D endp
  74. public  GetA2D ; Qbasic routine
  75. GetA2D   proc
  76. push bp
  77. mov  bp,sp
  78. mov bx,ss:[bp+6]
  79. mov ax,[bx]
  80. call new_stack
  81. call GetA2D_asm
  82. call old_stack
  83. mov [bx],ax
  84. pop bp
  85. retf 2
  86. GetA2D endp
  87. public  _PutA2DChannel
  88. _PutA2DChannel  proc ; C routine
  89. push bp
  90. mov  bp,sp
  91.         mov     ax,[bp+6]
  92. call new_stack
  93. call PutA2DChannel_asm
  94. call old_stack
  95. pop bp
  96. ret
  97. _PutA2DChannel endp
  98. public  PutA2DChannel ; Qbasic routine
  99. PutA2DChannel  proc
  100. push bp
  101. mov  bp,sp
  102. mov bx,ss:[bp+6]
  103. mov ax,[bx]
  104. call new_stack
  105. call PutA2DChannel_asm
  106. call old_stack
  107. mov [bx],ax
  108. pop bp
  109. retf 2
  110. PutA2DChannel endp
  111. public  _PutD2A
  112. _PutD2A  proc ; C routine
  113. push bp
  114. mov  bp,sp
  115.         mov     ax,[bp+6]
  116. call new_stack
  117. call PutD2A_asm
  118. call old_stack
  119. pop bp
  120. ret
  121. _PutD2A endp
  122. public  PutD2A ; Qbasic routine
  123. PutD2A  proc
  124. push bp
  125. mov  bp,sp
  126. mov bx,ss:[bp+6]
  127. mov ax,[bx]
  128. call new_stack
  129. call PutD2A_asm
  130. call old_stack
  131. mov [bx],ax
  132. pop bp
  133. retf 2
  134. PutD2A endp
  135. public  _PutD2AChannel
  136. _PutD2AChannel  proc ; C routine
  137. push bp
  138. mov  bp,sp
  139.         mov     ax,[bp+6]
  140. call new_stack
  141. call PutD2AChannel_asm
  142. call old_stack
  143. pop bp
  144. ret
  145. _PutD2AChannel endp
  146. public  PutD2AChannel ; Qbasic routine
  147. PutD2AChannel  proc
  148. push bp
  149. mov  bp,sp
  150. mov bx,ss:[bp+6]
  151. mov ax,[bx]
  152. call new_stack
  153. call PutD2AChannel_asm
  154. call old_stack
  155. mov [bx],ax
  156. pop bp
  157. retf 2
  158. PutD2AChannel endp
  159. public  _PutDriver
  160. _PutDriver  proc ; C routine
  161. push bp
  162. mov  bp,sp
  163.         mov     ax,[bp+6]
  164. call new_stack
  165. call PutDriver_asm
  166. call old_stack
  167. pop bp
  168. ret
  169. _PutDriver endp
  170. public  PutDriver ; Qbasic routine
  171. PutDriver  proc
  172. push bp
  173. mov  bp,sp
  174. mov bx,ss:[bp+6]
  175. mov ax,[bx]
  176. call new_stack
  177. call PutDriver_asm
  178. call old_stack
  179. mov [bx],ax
  180. pop bp
  181. retf 2
  182. PutDriver endp
  183. public  _PutDriverChannel
  184. _PutDriverChannel  proc ; C routine
  185. push bp
  186. mov  bp,sp
  187.         mov     ax,[bp+6]
  188. call new_stack
  189. call PutDriverChannel_asm
  190. call old_stack
  191. pop bp
  192. ret
  193. _PutDriverChannel endp
  194. public  PutDriverChannel ; Qbasic routine
  195. PutDriverChannel  proc
  196. push bp
  197. mov  bp,sp
  198. mov bx,ss:[bp+6]
  199. mov ax,[bx]
  200. call new_stack
  201. call PutDriverChannel_asm
  202. call old_stack
  203. mov [bx],ax
  204. pop bp
  205. retf 2
  206. PutDriverChannel endp
  207. public  _GetUARTChar
  208. _GetUARTChar  proc ; C routine
  209. push bp
  210. mov  bp,sp
  211.         mov     ax,[bp+6]
  212. call new_stack
  213. call GetUARTChar_asm
  214. call old_stack
  215. pop bp
  216. ret
  217. _GetUARTChar endp
  218. public  GetUARTChar ; Qbasic routine
  219. GetUARTChar proc
  220. push bp
  221. mov  bp,sp
  222. mov bx,ss:[bp+6]
  223. mov ax,[bx]
  224. call new_stack
  225. call GetUARTChar_asm
  226. call old_stack
  227. mov [bx],ax
  228. pop bp
  229. retf 2
  230. GetUARTChar endp
  231. public  _PutUARTChannel
  232. _PutUARTChannel  proc ; C routine
  233. push bp
  234. mov  bp,sp
  235.         mov     ax,[bp+6]
  236. call new_stack
  237. call PutUARTChannel_asm
  238. call old_stack
  239. pop bp
  240. ret
  241. _PutUARTChannel endp
  242. public  PutUARTChannel ; Qbasic routine
  243. PutUARTChannel proc
  244. push bp
  245. mov  bp,sp
  246. mov bx,ss:[bp+6]
  247. mov ax,[bx]
  248. call new_stack
  249. call PutUARTChannel_asm
  250. call old_stack
  251. mov [bx],ax
  252. pop bp
  253. retf 2
  254. PutUARTChannel endp
  255. public  _PutUARTChar
  256. _PutUARTChar  proc ; C routine
  257. push bp
  258. mov  bp,sp
  259.         mov     ax,[bp+6]
  260. call new_stack
  261. call PutUARTChar_asm
  262. call old_stack
  263. pop bp
  264. ret
  265. _PutUARTChar endp
  266. public  PutUARTChar ; Qbasic routine
  267. PutUARTChar proc
  268. push bp
  269. mov  bp,sp
  270. mov bx,ss:[bp+6]
  271. mov ax,[bx]
  272. call new_stack
  273. call PutUARTChar_asm
  274. call old_stack
  275. mov [bx],ax
  276. pop bp
  277. retf 2
  278. PutUARTChar endp
  279. public  _PutUARTBaud
  280. _PutUARTBaud  proc ; C routine
  281. push bp
  282. mov  bp,sp
  283.         mov     ax,[bp+6]
  284. call new_stack
  285. call PutUARTBaud_asm
  286. call old_stack
  287. pop bp
  288. ret
  289. _PutUARTBaud endp
  290. public  PutUARTBaud ; Qbasic routine
  291. PutUARTBaud proc
  292. push bp
  293. mov  bp,sp
  294. mov bx,ss:[bp+6]
  295. mov ax,[bx]
  296. call new_stack
  297. call PutUARTBaud_asm
  298. call old_stack
  299. mov [bx],ax
  300. pop bp
  301. retf 2
  302. PutUARTBaud endp
  303. public  _GetUARTRxStatus
  304. _GetUARTRxStatus  proc ; C routine
  305. push bp
  306. mov  bp,sp
  307.         mov     ax,[bp+6]
  308. call new_stack
  309. call GetUARTRxStatus_asm
  310. call old_stack
  311. pop bp
  312. ret
  313. _GetUARTRxStatus endp
  314. public  GetUARTRxStatus ; Qbasic routine
  315. GetUARTRxStatus proc
  316. push bp
  317. mov  bp,sp
  318. mov bx,ss:[bp+6]
  319. mov ax,[bx]
  320. call new_stack
  321. call GetUARTRxStatus_asm
  322. call old_stack
  323. mov [bx],ax
  324. pop bp
  325. retf 2
  326. GetUARTRxStatus endp
  327. public  _GetUARTTxStatus
  328. _GetUARTTxStatus  proc ; C routine
  329. push bp
  330. mov  bp,sp
  331.         mov     ax,[bp+6]
  332. call new_stack
  333. call GetUARTTxStatus_asm
  334. call old_stack
  335. pop bp
  336. ret
  337. _GetUARTTxStatus endp
  338. public  GetUARTTxStatus ; Qbasic routine
  339. GetUARTTxStatus proc
  340. push bp
  341. mov  bp,sp
  342. mov bx,ss:[bp+6]
  343. mov ax,[bx]
  344. call new_stack
  345. call GetUARTTxStatus_asm
  346. call old_stack
  347. mov [bx],ax
  348. pop bp
  349. retf 2
  350. GetUARTTxStatus endp
  351. public  _PutUARTWC
  352. _PutUARTWC  proc ; C routine
  353. push bp
  354. mov  bp,sp
  355.         mov     ax,[bp+6]
  356. call new_stack
  357. call PutUARTWC_asm
  358. call old_stack
  359. pop bp
  360. ret
  361. _PutUARTWC endp
  362. public  PutUARTWC ; Qbasic routine
  363. PutUARTWC proc
  364. push bp
  365. mov  bp,sp
  366. mov bx,ss:[bp+6]
  367. mov ax,[bx]
  368. call new_stack
  369. call PutUARTWC_asm
  370. call old_stack
  371. mov [bx],ax
  372. pop bp
  373. retf 2
  374. PutUARTWC endp
  375. public  _PutUARTWD
  376. _PutUARTWD  proc ; C routine
  377. push bp
  378. mov  bp,sp
  379.         mov     ax,[bp+6]
  380. call new_stack
  381. call PutUARTWD_asm
  382. call old_stack
  383. pop bp
  384. ret
  385. _PutUARTWD endp
  386. public  PutUARTWD ; Qbasic routine
  387. PutUARTWD proc
  388. push bp
  389. mov  bp,sp
  390. mov bx,ss:[bp+6]
  391. mov ax,[bx]
  392. call new_stack
  393. call PutUARTWD_asm
  394. call old_stack
  395. mov [bx],ax
  396. pop bp
  397. retf 2
  398. PutUARTWD endp
  399. public  _GetUARTRC
  400. _GetUARTRC  proc ; C routine
  401. push bp
  402. mov  bp,sp
  403.         mov     ax,[bp+6]
  404. call new_stack
  405. call GetUARTRC_asm
  406. call old_stack
  407. pop bp
  408. ret
  409. _GetUARTRC endp
  410. public  GetUARTRC ; Qbasic routine
  411. GetUARTRC proc
  412. push bp
  413. mov  bp,sp
  414. mov bx,ss:[bp+6]
  415. mov ax,[bx]
  416. call new_stack
  417. call GetUARTRC_asm
  418. call old_stack
  419. mov [bx],ax
  420. pop bp
  421. retf 2
  422. GetUARTRC endp
  423. public  _GetUARTRD
  424. _GetUARTRD  proc ; C routine
  425. push bp
  426. mov  bp,sp
  427.         mov     ax,[bp+6]
  428. call new_stack
  429. call GetUARTRD_asm
  430. call old_stack
  431. pop bp
  432. ret
  433. _GetUARTRD endp
  434. public  GetUARTRD ; Qbasic routine
  435. GetUARTRD proc
  436. push bp
  437. mov  bp,sp
  438. mov bx,ss:[bp+6]
  439. mov ax,[bx]
  440. call new_stack
  441. call GetUARTRD_asm
  442. call old_stack
  443. mov [bx],ax
  444. pop bp
  445. retf 2
  446. GetUARTRD endp
  447. ;-------------------------------------------------------------------------
  448. ;
  449. ; Data structures
  450. ;
  451. VersionNo dw 10 ; driver version number
  452. ad_board db 0 ; last A2D channel settings
  453. ad_side db 0
  454. ad_chan db 0
  455. da_board db 0 ; last D2A channel settings
  456. da_side db 0
  457. da_chip db 3
  458. da_bit db 0
  459. driver_board db 0 ; last driver channel settings
  460. driver_side db 0
  461. driver_chip db 5
  462. driver_bit db 0
  463. driver_bits db 16 dup(0) ; status of all the driver bits
  464. driver_bit_ptr dw offset driver_bits
  465. uart_board db 0 ; last uart channel settings
  466. uart_side db 0
  467. uart_chip db 2
  468. uart_cmd dw 16 dup(0E00Bh) ; default 9600,N82
  469. uart_cmd_ptr dw offset uart_cmd
  470. ; Read A/D channel #0 single-ended command string
  471. RD_0:
  472. db 50h,70h ; 1 Start
  473. db 40h,60h ; 0 A2
  474. db 40h,60h ; 0 A1
  475. db 50h,70h ; 1 A0
  476. db 40h,60h ; 0 Mode
  477. db 50h,70h ; 1 Single - Diff/
  478. db 50h,70h ; 1 PD1
  479. db 50h,70h ; 1 PD0
  480. db 40h,60h ; one extra clock
  481. db 40h ; idle the bus, data is high 
  482. db 0 ; null terminator
  483. ; Read A/D channel #1 single-ended
  484. RD_1:
  485. db 50h,70h ; 1 Start
  486. db 50h,70h ; 1 A2
  487. db 40h,60h ; 0 A1
  488. db 50h,70h ; 1 A0
  489. db 40h,60h ; 0 Mode
  490. db 50h,70h ; 1 Single - Diff/
  491. db 50h,70h ; 1 PD1
  492. db 50h,70h ; 1 PD0
  493. db 40h,60h ; one extra clock
  494. db 40h ; idle the bus, data is high 
  495. db 0 ; null terminator
  496. ; Read A/D channel #2 single-ended
  497. RD_2:
  498. db 50h,70h ; 1 Start
  499. db 40h,60h ; 0 A2
  500. db 50h,70h ; 1 A1
  501. db 40h,60h ; 0 A0
  502. db 40h,60h ; 0 Mode
  503. db 50h,70h ; 1 Single - Diff/
  504. db 50h,70h ; 1 PD1
  505. db 50h,70h ; 1 PD0
  506. db 40h,60h ; one extra clock
  507. db 40h ; idle the bus, data is high 
  508. db 0 ; null terminator
  509. ; Read A/D channel #3 single-ended
  510. RD_3:
  511. db 50h,70h ; 1 Start
  512. db 50h,70h ; 1 A2
  513. db 50h,70h ; 1 A1
  514. db 40h,60h ; 0 A0
  515. db 40h,60h ; 0 Mode
  516. db 50h,70h ; 1 Single - Diff/
  517. db 50h,70h ; 1 PD1
  518. db 50h,70h ; 1 PD0
  519. db 40h,60h ; one extra clock
  520. db 40h ; idle the bus, data is high 
  521. db 0 ; null terminator
  522. baud_table:
  523. dw 230 ,0 ; 230.4k baud
  524. dw 115 ,1 ; 115.2k baud
  525. dw 57 ,2 ; 57.6k baud
  526. dw 38 ,9 ; 38.4k baud
  527. dw 19 ,10 ; 19.2k baud
  528. dw 9600 ,11 ; 9600 baud
  529. dw 4800 ,12 ; 4800 baud
  530. dw 2400 ,13 ; 2400 baud
  531. dw 1200 ,14 ; 1200 baud
  532. dw 600 ,15 ; 600 baud
  533. dw 0 ,0 ; list end
  534. select_table:
  535. S0 db 70h,50h,60h,40h,60h,40h,60h,40h
  536. S1 db 70h,50h,60h,40h,60h,40h,70h,50h
  537. S2 db 70h,50h,60h,40h,70h,50h,60h,40h
  538. S3 db 70h,50h,60h,40h,70h,50h,70h,50h
  539. S4 db 70h,50h,70h,50h,60h,40h,60h,40h
  540. S5 db 70h,50h,70h,50h,60h,40h,70h,50h
  541. S6 db 70h,50h,70h,50h,70h,50h,60h,40h
  542. S7 db 70h,50h,70h,50h,70h,50h,70h,50h
  543. ;-------------------------------------------------------------------------
  544. ;
  545. ; GetVersion_asm - Returns the driver version number.  The least
  546. ; significant decimal digit is the minor revision, the most
  547. ; significant decimal digits are the major revision.
  548. ;
  549. GetVersion_asm:
  550. mov ax,[VersionNo]
  551. ret
  552. ;-------------------------------------------------------------------------
  553. ;
  554. ; GetA2DChannel_asm - Do one A/D conversion and return 12 bit 
  555. ; value right justified in AX
  556. ;
  557. GetA2D_asm:
  558. mov al,byte ptr [ad_chan]
  559. mov  bh,byte ptr [ad_board]
  560. mov bl,byte ptr [ad_side]
  561. push bx
  562. mov bl,20 ; calculate pointer to channel data
  563. mul bl
  564. mov ah,0
  565. mov si,offset RD_0
  566. add si,ax
  567. pop bx
  568. push bx
  569. mov dx,0F862h ; point to output port
  570. mov al,40h ; drop all but cs/
  571. out dx,al
  572. mov al,0 ; set CS0/ for write
  573. call select
  574. mov dx,0F864h ; configure all Port F pins for
  575. mov al,0 ; output
  576. out dx,al
  577. mov dx,0F862h ; point to output port
  578. cmd_loop:
  579. mov al,cs:[si] ; get a byte
  580. cmp al,0 ; done?
  581. je cmd_done ; yes, leave
  582. out dx,al ; no, send it
  583. inc si ; bump pointer
  584. jmp cmd_loop ; and loop
  585. cmd_done:
  586. mov dx,0F864h ; configure data line for read
  587. mov al,10h
  588. out dx,al
  589. mov cx,16 ; 16 bits to get
  590. mov bx,0 ; result goes here
  591. mov ah,0
  592. in_loop:
  593. mov dx,0F860h
  594. in al,dx ; data is in bit 4
  595. rcl al,1 ; rotate it into carry
  596. rcl al,1
  597. rcl al,1
  598. rcl al,1
  599. rcl bx,1 ; rotate it from carry to bx
  600. mov dx,0F862h ; point to output port
  601. mov al,70h ; set the clock high
  602. out dx,al
  603. mov al,50h
  604. out dx,al
  605. loop in_loop
  606. shr bx,1 ; last 3 bits are zeros, shift 
  607. shr bx,1 ; 12 bit value over
  608. shr bx,1
  609. shr bx,1
  610. and bx,0FFFh
  611. mov dx,0F862h ; idle the bus
  612. mov al,40h
  613. out dx,al
  614. mov ax,bx
  615. call bus_reset
  616. pop bx
  617. sti
  618. ret
  619. ;-------------------------------------------------------------------------
  620. ;
  621. ; PutA2DChannel_asm gets the extended channel from the caller and
  622. ; converts it to board, side, and channel numbers and stores
  623. ; the result.
  624. ;
  625. PutA2DChannel_asm:
  626. push ax
  627. mov ah,al ; make 2 copies
  628. mov bl,al
  629. and al,3 ; channel
  630. mov byte ptr [ad_chan],al ; store it
  631. and ah,4 ; board
  632. shr ah,1
  633. shr  ah,1
  634. mov byte ptr [ad_side],ah ; store it
  635. and bl,0F8h
  636. shr bl,1
  637. shr bl,1
  638. shr bl,1
  639. mov byte ptr [ad_board],bl
  640. pop ax
  641. ret
  642. ;-------------------------------------------------------------------------
  643. ;
  644. ; PutD2AChannel_asm converts AL into a chip, side, and board select
  645. ; and stores them for PutD2A_asm.
  646. ;
  647. PutD2AChannel_asm:
  648. push ax
  649. push bx
  650. and al,1Fh ; 8 boards max
  651. mov bh,al ; make 2 copies
  652. mov  bl,al
  653. and al,1 ; al is chip select
  654. add al,3
  655. shr bl,1 ; bl is side
  656. and bl,1
  657. shr bh,1 ; bh is board
  658. shr bh,1
  659. and bh,7 ; 8 boards max
  660. mov byte ptr [da_chip],al
  661. mov byte ptr [da_side],bl
  662. mov byte ptr [da_board],bh
  663. pop bx
  664. pop ax
  665. ret
  666. ;-------------------------------------------------------------------------
  667. ;
  668. ; PutD2A_asm sends the lower 12 bits in ax to the selected D2A
  669. ;
  670. PutD2A_asm:
  671. push ax
  672. push ax
  673. mov al,byte ptr [da_chip]
  674. mov bl,byte ptr [da_side]
  675. mov bh,byte ptr [da_board]
  676. call select
  677. pop bx
  678. and bx,0FFFh
  679. mov al,40h ; set data low
  680. mov dx,0F862h
  681. out dx,al
  682. mov dx,0F864h ; configure all pins as outputs
  683. mov al,0 ; 
  684. out dx,al
  685. mov cl,16 ; loop counter
  686. rcl bx,1 ; get the first data bit in carry
  687. mov dx,0F862h ; output port
  688. da_shift_loop:
  689. mov al,60h ; clk hi with data zero
  690. jnc da_data_low ; all done if carry is 0
  691. mov al,70h ; clk hi with data one
  692. da_data_low:
  693. out dx,al ; do it
  694. and al,0D0h ; lower clk
  695. out dx,al ; send it
  696. rcl bx,1 ; rotate
  697. dec cl
  698. jnz da_shift_loop
  699. call bus_reset
  700. pop ax
  701. ret
  702. ;-------------------------------------------------------------------------
  703. ;
  704. ; PutDriverChannel_asm takes an integer in the range of 0-63 in 
  705. ; ax and converts it into a board number, side number and an index
  706. ; into the array of previous driver bit states.
  707. ;
  708. PutDriverChannel_asm:
  709. push ax ; save ax for caller
  710. and al,3fh ; only look at lower 6 bits
  711. mov bh,al ; make 3 copies
  712. mov bl,al
  713. mov ah,al
  714. shr bl,1 ; form the side
  715. shr bl,1
  716. and bl,1
  717. mov [driver_side],bl
  718. shr bh,1 ; form the board
  719. shr bh,1
  720. shr bh,1
  721. and bh,7
  722. mov [driver_board],bh
  723. and ah,3
  724. mov [driver_bit],ah
  725. mov ah,0
  726. shr al,1 ; form the pointer to the bitfield
  727. shr al,1
  728. and al,0Fh
  729. mov si,offset driver_bits ; point to array
  730. add si,ax ; index into it 
  731. mov [driver_bit_ptr],si ; store the pointer
  732. pop ax
  733. ret
  734. ;-------------------------------------------------------------------------
  735. ;
  736. ; PutDriver_asm sets or cleared the relay driver channel selected
  737. ; by PutDriver_Channel.  It has to pull up the previous 4 bits of
  738. ; the channel group, set or clear the specified channel bit, store 
  739. ; the updated nibble and shift it out to the drivers.
  740. ;
  741. PutDriver_asm:
  742. push ax
  743. cmp al,0 ; convert al to one or zero
  744. je zero
  745. mov al,00000001B ; OR mask for one
  746. mov ah,11111111B ; AND mask for one
  747. jmp one
  748. zero:
  749. mov al,00000000B ; OR mask for zero
  750. mov ah,11111110B ; AND mask for zero
  751. one:
  752. mov cl,[driver_bit] ; get bit position
  753. bit_shift:
  754. cmp cl,0 ; done?
  755. je done_shifting
  756. rol al,1
  757. rol ah,1
  758. dec cl
  759. jmp bit_shift ; now our bit is in the same position
  760. ; as in the nibble we will shift out
  761. done_shifting:
  762. mov si,[driver_bit_ptr] ; get pointer to our nibble
  763. mov bl,[si] ; get our nibble
  764. or bl,al ; do the OR
  765. and bl,ah ; do the AND
  766. mov [si],bl ; store the updated nibble
  767. push bx
  768. mov bh,[driver_board] ; select the 4 bit group
  769. mov bl,[driver_side] ; from the channel specified
  770. mov al,[driver_chip] ; by PutDriverChannel
  771. call select
  772. pop bx
  773. shl bl,1 ; left justify the data
  774. shl bl,1
  775. shl bl,1
  776. shl bl,1
  777. and bl,0F0h ; get rid of any garbage
  778. mov al,40h ; set data low
  779. mov dx,0F862h
  780. out dx,al
  781. mov dx,0F864h ; configure all pins as outputs
  782. mov al,0 ; 
  783. out dx,al
  784. mov cl,5 ; loop counter
  785. rcl bl,1 ; get the first data bit in carry
  786. mov dx,0F862h ; output port
  787. shift_loop:
  788. mov al,60h ; clk hi with data zero
  789. jnc data_low ; all done if carry is 0
  790. mov al,70h ; clk hi with data one
  791. data_low:
  792. out dx,al ; do it
  793. and al,0D0h ; lower clk
  794. out dx,al ; send it
  795. rcl bl,1 ; rotate
  796. dec cl
  797. jnz shift_loop
  798. call bus_reset
  799. pop ax ; restore caller's value
  800. ret
  801. ;-------------------------------------------------------------------------
  802. ;
  803. ; PutUARTChannel_asm -  Selects the current UART, 0-15
  804. ;
  805. PutUARTChannel_asm:
  806. push ax ; save a copy for caller
  807. mov ah,al ; and another copy for here
  808. and al,00001111B ; 16 max
  809. mov bl,al ; form side number
  810. and al,00000001B
  811. mov [uart_side],al
  812. mov bh,ah ; form board number
  813. shr bh,1
  814. and bh,00000111B
  815. mov [uart_board],bh
  816. pop ax ; set pointer to write config word
  817. push ax
  818. mov si,offset uart_cmd
  819. shl ax,1
  820. and ax,01Eh ; 16 entries max
  821. add si,ax
  822. mov [uart_cmd_ptr],si
  823. pop ax
  824. ret
  825. ;-------------------------------------------------------------------------
  826. ;
  827. ; PutUARTChar_asm - Sends the char in al out the current UART - blocking
  828. ;
  829. PutUARTChar_asm:
  830. push ax
  831. call send_char_wait
  832. pop ax
  833. ret
  834. ;-------------------------------------------------------------------------
  835. ;
  836. ; PutUARTBaud_asm - Sets the baud rate for the current UART
  837. ;
  838. PutUARTBaud_asm:
  839. push ax
  840. mov si,offset baud_table ; point to the baud rate translation
  841. baud_loop: ; table
  842. cmp ax,[si] ; get entry
  843. je found_baud ; match?
  844. cmp [si],word ptr 0 ; no, last entry?
  845. je baud_not_found ; yes, all done
  846. add si,4 ; no, index to next entry
  847. jmp baud_loop ; and back through
  848. found_baud: ; we have a match
  849. add si,2 ; point to uart baud code
  850. mov bx,[si] ; get it
  851. mov si,[uart_cmd_ptr] ; point to the previous uart command
  852. mov ax,[si] ; get it
  853. and ax,0FFF0h ; clear the baud bits
  854. or ax,bx ; OR in the selected baud
  855. mov [si],ax ; store it
  856. call set_uart ; and send it
  857. baud_not_found:
  858. pop ax
  859. ret
  860. ;-------------------------------------------------------------------------
  861. ;
  862. ; GetUARTRxStatus - Get Rx status bit in AX, 1 equals char waiting
  863. ;
  864. GetUARTRxStatus_asm:
  865. call GetUARTRC_asm
  866. rol ax,1
  867. and ax,1
  868. ret
  869. ;-------------------------------------------------------------------------
  870. ;
  871. ; GetUARTTxStatus - Get TX status bit in AX, 1 equals ok to send
  872. ;
  873. GetUARTTxStatus_asm:
  874. call GetUARTRC_asm
  875. rol ax,1
  876. rol ax,1
  877. and ax,1
  878. ret
  879. ;-------------------------------------------------------------------------
  880. ;
  881. ; GetUARTChar_asm - Gets a char from the current UART - blocking
  882. ;
  883. GetUARTChar_asm:
  884. call get_char_status ; char available?
  885. jnc GetUARTChar_asm ; no, loop checking
  886. call get_char ; yes, get it
  887. mov ah,0
  888. ret
  889. ;-------------------------------------------------------------------------
  890. ;
  891. ; PutUARTWC_asm - Writes AX to the write configuration reg of the
  892. ; current UART
  893. ;
  894. PutUARTWC_asm:
  895. mov bx,ax
  896. or bl,11000000b ; make sure top 2 bits are set
  897. mov [uart_cmd_ptr],bx ; store it for next time
  898. call uart
  899. mov ax,bx
  900. ret
  901. ;-------------------------------------------------------------------------
  902. ;
  903. ; PutUARTWD_asm - Writes AX to the Write Data reg of the current UART
  904. ;
  905. PutUARTWD_asm:
  906. mov bx,ax
  907. or bl,10000000b ; make sure bit 15 is set
  908. and bl,10111111b ; and bit 14 is cleared
  909. call uart
  910. mov ax,bx
  911. ret
  912. ;-------------------------------------------------------------------------
  913. ;
  914. ; GetUARTRC_asm - Returns the read configuration register in AX from
  915. ; the current UART
  916. ;
  917. GetUARTRC_asm:
  918. mov bx,4000h
  919. call uart
  920. mov ax,bx
  921. ret
  922. ;-------------------------------------------------------------------------
  923. ;
  924. ; GetUARTRD_asm - Returns the read data register in AX from the 
  925. ; current UART
  926. ;
  927. GetUARTRD_asm:
  928. mov bx,0
  929. call uart
  930. mov ax,bx
  931. ret
  932. ;-------------------------------------------------------------------------
  933. ;
  934. ; Send_Char_Wait - Checks to see if it's ok to send a char, if it
  935. ;  is, sends the char in AL.  If not, waits til ok
  936. ;  then sends char in AL.
  937. ;
  938. send_char_wait:
  939. call send_char_status ; ok to send?
  940. jnc send_char_wait ; no, loop checking
  941. call send_char ; yes, send it
  942. ret
  943. ;-------------------------------------------------------------------------
  944. ;
  945. ; Send_Char_Status - Returns with carry set if ok to send char
  946. ;
  947. send_char_status:
  948. push ax
  949. push bx ; needed for uart command
  950. mov bx,4000h ; read data register cmd
  951. call uart ; do it
  952. shl bh,1 ; get the T bit
  953. shl bh,1 ; in carry
  954. pop bx ; restore bx
  955. pop ax
  956. ret
  957. ;-------------------------------------------------------------------------
  958. ;
  959. ; Send_Char - Unconditionally sends char in AL
  960. ;
  961. send_char:
  962. push ax ; save AX
  963. mov bl,al ; move the char to BL
  964. mov bh,80h ; send command
  965. call uart ; send it
  966. pop ax
  967. ret
  968. ;-------------------------------------------------------------------------
  969. ;
  970. ; Get_Char_Status - Returns with carry flag set if char available
  971. ;
  972. get_char_status:
  973. push bx ; needed for uart command
  974. mov bx,4000 ; read data register cmd
  975. call uart ; do it
  976. shl bh,1 ; get the R bit
  977. pop bx ; restore bx
  978. ret
  979. ;-------------------------------------------------------------------------
  980. ;
  981. ; Get_Char - Gets a char from UART without testing. Char returned
  982. ;    in AL.
  983. ;
  984. get_char:
  985. push bx ; needed for uart command
  986. mov bx,0 ; read data register cmd
  987. call uart ; do it
  988. mov al,bl ; we have data, move to al
  989. pop bx ; restore bx
  990. ret
  991. ;-------------------------------------------------------------------------
  992. ;
  993. ; Set_UART - Sends AX to the UART write config reg
  994. ;
  995. set_uart:
  996. push ax ; data is passed to uart in bx
  997. mov bx,ax
  998. call uart
  999. pop ax
  1000. ret
  1001. ;-------------------------------------------------------------------------
  1002. ;
  1003. ; Uart - Simultaneously shift in and out the 16 bit value in BX
  1004. ;
  1005. uart:
  1006. push ax
  1007. push cx
  1008. push dx
  1009. push bx
  1010. mov bh,byte ptr [uart_board] ; get board, side and chip from mem
  1011. mov bl,byte ptr [uart_side]
  1012. mov al,byte ptr [uart_chip]
  1013. call select
  1014. mov al,40h ; set data low
  1015. mov dx,0F862h
  1016. out dx,al
  1017. mov dx,0F864h ; configure data as open-drain
  1018. mov al,10h ; CLK, RESET, and CS as comp. out
  1019. out dx,al
  1020. pop bx
  1021. mov cl,16 ; loop counter
  1022. rcl bx,1 ; get the first data bit in carry
  1023. u_shift_loop:
  1024. mov al,40h ; low clock, data 0
  1025. jnc u_data_low ; all done if carry is 0
  1026. mov al,50h ; no, make data 1
  1027. u_data_low:
  1028. mov dx,0F862h ; drive it out
  1029. out dx,al
  1030. mov al,70h ; raise clk and data
  1031. out dx,al ; drive it out
  1032. mov dx,0F860h
  1033. in al,dx ; get our data
  1034. rcl al,1
  1035. rcl al,1
  1036. rcl al,1
  1037. rcl al,1
  1038. rcl bx,1 ; rotate
  1039. dec cl
  1040. jnz u_shift_loop
  1041. call bus_reset
  1042. pop dx
  1043. pop cx
  1044. pop ax
  1045. ret
  1046. ;-------------------------------------------------------------------------
  1047. ;
  1048. ; Select - Activates the chip select for the proper device
  1049. ;  BH = Board to select, 0 - 8
  1050. ;  BL = Side to select, 0 - 1
  1051. ;  AL = Chip Select, 0 - 5
  1052. ;
  1053. select:
  1054. call bus_reset ; reset the bus to start
  1055. push ax ; save the chip select
  1056. mov cl,bh ; get board in cl
  1057. board_select_loop:
  1058. cmp cl,0 ; any to do
  1059. je side_select ; no, do the side
  1060. mov al,7 ; select next board
  1061. call bus_channel ; do it
  1062. dec cl ; decrement board count
  1063. jmp board_select_loop ; and loop
  1064. side_select:
  1065. cmp bl,0 ; if zero, don't do anything
  1066. je chip_select
  1067. mov al,6 ; select side 1
  1068. call bus_channel
  1069. chip_select:
  1070. pop ax ; get the chip select
  1071. call bus_channel ; and do it
  1072. ret
  1073. ;-------------------------------------------------------------------------
  1074. ;
  1075. ; Reset - send a reset pulse to all of the decoders on the bus
  1076. ;
  1077. bus_reset:
  1078. push ax
  1079. push dx
  1080. mov dx,0F862h ; put a zero in the output ports
  1081. mov al,0
  1082. out dx,al
  1083. mov dx,0F864h ; select all outputs
  1084. out dx,al
  1085. mov dx,0F862h
  1086. mov al,40h ; lift reset
  1087. out dx,al
  1088. pop dx
  1089. pop ax
  1090. ret
  1091. ;-------------------------------------------------------------------------
  1092. ;
  1093. ; Select selects the channel passed in AL
  1094. ;
  1095. bus_channel:
  1096. push bx
  1097. push si ; going to need some registers
  1098. push dx
  1099. push ax
  1100. mov bl,al ; channel needs to go into bl
  1101. mov bh,0
  1102. shl bl,1 ; multiply bl times 8 for proper
  1103. shl bl,1 ; table offset
  1104. shl bl,1
  1105. mov si,offset select_table ; point to first entry
  1106. add si,bx ; add in offset
  1107. mov bx,8 ; loop counter now
  1108. mov dx,0F862h ; point to port
  1109. send_loop:
  1110. mov al,cs:[si] ; get the byte
  1111. out dx,al ; send it
  1112. inc si ; bump pointer
  1113. dec bx ; unbump counter
  1114. jnz send_loop ; done?
  1115. mov al,050h ; idle the bus
  1116. out dx,al
  1117. pop ax
  1118. pop dx
  1119. pop si
  1120. pop bx
  1121. ret
  1122. ;-----------------------------------------------------------------------------
  1123. ;
  1124. ; New_stack sets up a new stack and saves all of the caller's 
  1125. ; registers except AX. DS and ES are set to the same code 
  1126. ; segment as CS.
  1127. ;
  1128. new_stack:
  1129. mov cs:[old_ax],ax ; preserve ax
  1130. mov cs:[old_bx],bx ; and bx
  1131. pop bx ; get our return in bx
  1132. cli ; interrupts off while changing stack
  1133. mov ax,ss ; get stack seg
  1134. mov cs:[old_ss],ax ; store it
  1135. mov cs:[old_sp],sp ; store old stack pointer
  1136. mov ax,cs ; get our code seg
  1137. mov ss,ax ; set our stack seg to it
  1138. mov sp,offset top_stack ; point to our stack
  1139. sti
  1140. push cx ; save caller's registers
  1141. push dx
  1142. push si
  1143. push di
  1144. push bp
  1145. push ds
  1146. push es
  1147. push bx ; push caller's return adddress
  1148. mov ds,ax ; set small model ds and es
  1149. mov es,ax
  1150. mov ax,cs:[old_ax] ; restore ax
  1151. mov bx,cs:[old_bx] ; and bx
  1152. ret ; and return to caller
  1153. ;-----------------------------------------------------------------------------
  1154. ;
  1155. ; Old_stack restores the old stack and the caller's registers 
  1156. ; except AX.
  1157. ;
  1158. old_stack:
  1159. mov cs:[old_ax],ax ; preserve ax
  1160. pop bx ; get our return in bx
  1161. pop es ; restore caller's registers
  1162. pop ds
  1163. pop bp
  1164. pop di
  1165. pop si
  1166. pop dx
  1167. pop cx
  1168. cli ; interrupts off while changing stack
  1169. mov sp,cs:[old_sp] ; get old stack pointer
  1170. mov ax,cs:[old_ss] ; get old stack seg
  1171. mov ss,ax ; install it
  1172. sti
  1173. push bx ; push caller's return address
  1174. mov ax,cs:[old_ax] ; restore ax
  1175. mov bx,cs:[old_bx] ; and bx
  1176. ret ; and return to caller
  1177. old_ax dw 0 ; temp register storage for 
  1178. old_bx dw 0 ; new_stack and old_stack
  1179. old_sp dw 0
  1180. old_ss dw 0
  1181. dw 200h dup(0) ; new stack
  1182. top_stack:
  1183. end