home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / packetdrivers.tar.gz / pd.tar / src / eep17.inc < prev    next >
Text File  |  1995-06-25  |  18KB  |  696 lines

  1. ;************************************************************************;
  2. ;*                                    *;
  3. ;*            EEP17.INC                    *;
  4. ;*                                    *;
  5. ;*  EEPROM configuration routines for the ATI AT-1700 Adapters.        *;
  6. ;*                                    *;
  7. ;*  Copyright (c) 1992, 1993, Allied Telesis, Inc.  All Rights Reserved.*;
  8. ;*                                    *;
  9. ;************************************************************************;
  10.  
  11.  
  12. DATASEG    SEGMENT
  13.  
  14.  
  15.     ifdef    CODE386        ; 386 "flat" model
  16. CONFIG_PTR    equ    ESI
  17.     else            ; all other models
  18. CONFIG_PTR    equ    SI
  19.     endif
  20.  
  21.     ifndef    @Version
  22. @Version equ    000
  23.     endif
  24.  
  25.  
  26. ; EtherCoupler Register addresses (offsets from IOBASE):
  27. DLCR7_OFFSET    equ    7        ; Config (register select) register
  28. DLCR8_OFFSET    equ    8        ; Node ID register
  29. EESKCS_OFFSET    equ    16        ; EESKCS register - see below
  30. EEDP_OFFSET    equ    17        ; EEDP register - see below
  31. IOBAI_OFFSET    equ    18        ; IOBAI register
  32. JLC_OFFSET    equ    19        ; JumperLess Configuration register
  33. IDROM_OFFSET    equ    24        ; first byte of IDROM
  34.  
  35. ; EtherCoupler's EESKCS EEPROM control register:
  36. DATA_IN        equ    80h    ; serial data in (write)
  37. CLOCK        equ    40h    ; serial clock (write)
  38. DATA_OUT    equ    04h    ; serial data out (read)
  39. CHIP_SEL    equ    20h    ; Chip Select
  40.  
  41. ; EtherCoupler's EDDP EEPROM Data register:
  42. SB        equ    80h    ; "Start Bit"
  43. READ        equ    80h    ; Command Code:  Read
  44. EWEN        equ    30h    ; Command Code:  Write Enable
  45. WRITE        equ    40h    ; Command Code:  Write
  46. WRALL        equ    10h    ; Command Code:  Write All
  47. EWDS        equ    00h    ; Command Code:  Write Disable
  48.  
  49. ; EEPROM byte (word) locations:
  50. CONFIG_ADDR    equ    0/2    ; Configuration Byte - see below
  51. ETHERNET_ADDR    equ    8/2    ; Ethernet (MAC) address of this adapter
  52. BMPR13_ADDR    equ    24/2    ; value to be used in BMPR13 - see below
  53. BRD_TYPE_ADDR    equ    30/2    ; Board type code - see below
  54. BRD_REV_ADDR    equ    31/2    ; Board rev level code
  55.  
  56. ; JLC register and Configuration Byte (EEPROM location 0) format:
  57. IO_BASE_MASK    equ    007h    ; bits 0-2 = I/O Base code - see below
  58. MEM_BASE_MASK    equ    038h    ; bits 3-5 = Boot PROM Base code - see below
  59. IRQ_MASK    equ    0C0h    ; bits 6-7 = IRQ code - see below
  60.  
  61. ; I/O Base code (JLC bits 0-2):
  62. BASE_IO_260    equ    00h
  63. BASE_IO_280    equ    01h
  64. BASE_IO_2A0    equ    02h
  65. BASE_IO_240    equ    03h
  66. BASE_IO_340    equ    04h
  67. BASE_IO_320    equ    05h
  68. BASE_IO_380    equ    06h
  69. BASE_IO_300    equ    07h
  70.  
  71. ; Boot PROM Base code (JLC bits 3-5):
  72. ROM_BASE_C400        equ    00h
  73. ROM_BASE_C800        equ    08h
  74. ROM_BASE_CC00        equ    10h
  75. ROM_BASE_D000        equ    18h
  76. ROM_BASE_D400        equ    20h
  77. ROM_BASE_D800        equ    28h
  78. ROM_BASE_DC00        equ    30h
  79. ROM_BASE_DISABLED    equ    38h
  80.  
  81. ; IRQ code (JLC bits 6-7):
  82. IRQ_3        equ    000h
  83. IRQ_4        equ    040h
  84. IRQ_5        equ    080h
  85. IRQ_9        equ    0C0h
  86.  
  87. ; BMPR13 Register bits (EEPROM location 24):
  88. MAU_SEL_MASK    equ    18h        ; bits 3&4 = Port selection
  89. UTP_PORT        equ    08h        ; UTP port
  90. OTHER_PORT        equ    18h        ; "Other" (BNC/Fiber) port
  91. AUTO_SELECT        equ    00h        ; "Auto Select"
  92. TPTYPE_MASK    equ    44h        ; bits 2&6 = Twisted Pair Type selection
  93. UTP_MEDIA_TYPE        equ    40h        ; 100ohm UTP or STP cabling
  94. STP_MEDIA_TYPE        equ    04h        ; 150ohm STP cabling
  95.  
  96. ; Board Type code (EEPROM location 30):
  97. IS_A_1700T    equ    0        ; AT-1700T Twisted-Pair only
  98. IS_A_1700BT    equ    1        ; AT-1700BT Twisted-Pair plus BNC
  99. IS_A_1700FT    equ    2        ; AT-1700FT Twisted-Pair plus FOIRL
  100.  
  101. DATASEG    ENDS
  102.  
  103.  
  104. CODESEG    SEGMENT
  105.  
  106. DELAY_750 MACRO
  107.     ; One CPU clock cycle = 25ns at 40Mhz CPU clock frequency
  108.     ; jmp short = (min) 8 cycles on a 386 = 200ns per jump
  109.     ; times 4 = at least 800ns on a 40Mhz 386
  110.     jmp short $+2
  111.     jmp short $+2
  112.     jmp short $+2
  113.     jmp short $+2
  114.     ENDM
  115.  
  116. DELAY_250 MACRO
  117.     ; times 2 = at least 400ns on a 40Mhz 386
  118.     jmp short $+2
  119.     jmp short $+2
  120.     ENDM
  121.  
  122.  
  123. ;************************************************************************;
  124. ;*                                    *;
  125. ;*  VerifyBoard                                *;
  126. ;*    Function: 1) reset the board                    *;
  127. ;*          2) read the IRQ and BMPR13 value from the EEPROM.    *;
  128. ;*    Input:    DI = base I/O address of the AT-1700 board        *;
  129. ;*    Output: AH = IRQ from JLC register if success            *;
  130. ;*        AL = BMPR13 value register if success            *;
  131. ;*        AX = FFFFh if failure (not an AT-1700 or config error)    *;
  132. ;*        registers used are preserved                *;
  133. ;*                                    *;
  134. ;************************************************************************;
  135.  
  136. VerifyBoard proc    near
  137.  
  138.     push    cx
  139.     push    dx
  140.  
  141.     xor    ax, ax
  142.     mov    dx, di            ;reset the NIC
  143.     add    dx, IDROM_OFFSET
  144.     out    dx, al
  145.  
  146.     call    is_there_AT1700        ;read the register pattern
  147.     jnc    get_irq
  148.     mov    ax, 0ffffh        ;it's not there
  149.     pop    dx
  150.     pop    cx
  151.     ret
  152.  
  153. get_irq:
  154.     mov    dx, DI
  155.     add    dx, JLC_OFFSET        ;read JLC register
  156.     in    al, dx
  157.  
  158.     ; AL now contains Base IO and IRQ
  159.     and    al, IRQ_MASK
  160.     mov    cl, 3
  161.     cmp    al, IRQ_3
  162.      je    get_bmpr
  163.     mov    cl, 4
  164.     cmp    al, IRQ_4
  165.      je    get_bmpr
  166.     mov    cl, 5
  167.     cmp    al, IRQ_5
  168.      je    get_bmpr
  169.     mov    cl, 9
  170.  
  171. get_bmpr:
  172.     call    read_BMPR_val        ;al = BMPR13 register value
  173.     mov    ah, cl
  174.  
  175.     pop    dx
  176.     pop    cx
  177.     ret
  178.  
  179. VerifyBoard endp
  180.  
  181.  
  182. ;************************************************************************;
  183. ;*                                    *;
  184. ;*  GetIRQAndVerify                            *;
  185. ;*    Function: Get the IRQ and read MAC addr from EEPROM to verify    *;
  186. ;*        the board                        *;
  187. ;*    Input:    DI = base I/O address of the AT-1700 board        *;
  188. ;*        DS:(E)SI => caller's buffer where to put MAC address.    *;
  189. ;*    Output: the board's MAC address is placed in the caller's bfr.    *;
  190. ;*        AX = IRQ from JLC register if success            *;
  191. ;*        AX = FFFFh if failure (not an AT-1700 or config error)    *;
  192. ;*        registers used are preserved                *;
  193. ;*                                    *;
  194. ;************************************************************************;
  195.  
  196. GetIRQAndVerify proc    near
  197.  
  198.     push    cx            ; save caller's registers
  199.     push    dx
  200.  
  201.     call    Verify_JLC        ; read & verify JLC (returns ah = JLC)
  202.     mov    al, ah            ; al = JLC value
  203.  
  204.     xor    cx, cx            ; determine configured IRQ value
  205.     and    al, IRQ_MASK
  206.     mov    cl, 3
  207.     cmp    al, IRQ_3
  208.      je    VerifyMACAddr
  209.     mov    cl, 4
  210.     cmp    al, IRQ_4
  211.      je    VerifyMACAddr
  212.     mov    cl, 5
  213.     cmp    al, IRQ_5
  214.      je    VerifyMACAddr
  215.     mov    cl, 9
  216.  
  217. VerifyMACAddr:
  218.     call    read_mac_addr        ; read the board's MAC address
  219.     cmp    word ptr [CONFIG_PTR], 0    ; (validate it)
  220.      jne    FailToVerify
  221.     cmp    byte ptr [CONFIG_PTR+2], 0F4h
  222.      jne    FailToVerify
  223.  
  224.     mov    ax, cx            ; return IRQ value in ax
  225.     pop    dx            ; restore caller's registers
  226.     pop    cx
  227.     ret                ; return to caller
  228.  
  229. FailToVerify:
  230.     mov    ax, 0ffffh
  231.     pop    dx
  232.     pop    cx
  233.     ret
  234.  
  235. GetIRQAndVerify endp
  236.  
  237. ;************************************************************************;
  238. ;*                                    *;
  239. ;*  Verify_JLC                                *;
  240. ;*    Function: Get the JLC and do a sanity check on it.        *;
  241. ;*    Input:    DI = base I/O address of the AT-1700 board        *;
  242. ;*    Output:    AH = JLC register value                    *;
  243. ;*        ZF = TRUE (jz) on success                *;
  244. ;*        ZF = FALSE (jnz) on failure                *;
  245. ;*        registers used are preserved                *;
  246. ;*                                    *;
  247. ;************************************************************************;
  248.  
  249. Verify_JLC    PROC    NEAR
  250.  
  251.     mov    dx, DI
  252.     add    dx, JLC_OFFSET
  253.     in    al, dx            ; read the JLC register
  254.     mov    ah, al            ; save it for caller in AH
  255.  
  256.     and    al, IO_BASE_MASK
  257.     cmp    di, 0300h
  258.      jne    next_io_1
  259.     cmp    al, BASE_IO_300
  260.      je    JLC_verified
  261.     jmp    JLC_failure
  262. next_io_1:
  263.     cmp    di, 0320h
  264.      jne    next_io_2
  265.     cmp    al, BASE_IO_320
  266.      je    JLC_verified
  267.     jmp    JLC_failure
  268. next_io_2:
  269.     cmp    di, 0340h
  270.      jne    next_io_3
  271.     cmp    al, BASE_IO_340
  272.      je    JLC_verified
  273.     jmp    JLC_failure
  274. next_io_3:
  275.     cmp    di, 0380h
  276.      jne    next_io_4
  277.     cmp    al, BASE_IO_380
  278.      je    JLC_verified
  279.     jmp    JLC_failure
  280. next_io_4:
  281.     cmp    di, 0240h
  282.      jne    next_io_5
  283.     cmp    al, BASE_IO_240
  284.      je    JLC_verified
  285.     jmp    JLC_failure
  286. next_io_5:
  287.     cmp    di, 0260h
  288.      jne    next_io_6
  289.     cmp    al, BASE_IO_260
  290.      je    JLC_verified
  291.     jmp    JLC_failure
  292. next_io_6:
  293.     cmp    di, 0280h
  294.      jne    next_io_7
  295.     cmp    al, BASE_IO_280
  296.      je    JLC_verified
  297.     jmp    JLC_failure
  298. next_io_7:
  299.     cmp    di, 02A0h
  300.      jne    JLC_failure
  301.     cmp    al, BASE_IO_2A0
  302.      jne    JLC_failure
  303.  
  304. JLC_verified:
  305. JLC_failure:
  306.     ret        ; return to caller
  307.  
  308. Verify_JLC endp
  309.  
  310.  
  311. ;************************************************************************;
  312. ;*                                    *;
  313. ;*  is_there_AT1700                            *;
  314. ;*    Function: determines if this is an AT-1700 at this location.    *;
  315. ;*    Input:    DI = base I/O of the presumed AT-1700 adapter card.    *;
  316. ;*    Output: clc (carry clear) if AT1700 is found, else        *;
  317. ;*        stc (carry set) if not.                    *;
  318. ;*        registers used are preserved                *;
  319. ;*                                    *;
  320. ;************************************************************************;
  321.  
  322. is_there_AT1700 PROC NEAR
  323.  
  324.     push    ax
  325.     push    dx
  326.  
  327.     ;  First do a pattern check - a just powered-up or reset AT-1700 board
  328.     ;  will have a known pattern to its I/O registers.
  329.     mov    dx, DI
  330.     in    al, dx            ; check DLCR0
  331.     and    al, NOT 40h        ; remove NET BUSY bit
  332.      jz    try_2            ;   all other bits should be zero
  333.     jmp    not_the_reset_pattern
  334. try_2:
  335.     inc    dx
  336.     in    al, dx            ; check DLCR1
  337.     or    al, al
  338.      jz    try_3
  339.     jmp    not_the_reset_pattern
  340. try_3:
  341.     inc    dx
  342.     in    al, dx            ; check DLCR2
  343.     or    al, al
  344.      jz    try_4
  345.     jmp    not_the_reset_pattern
  346. try_4:
  347.     inc    dx
  348.     in    al, dx            ; check DLCR3
  349.     or    al, al
  350.      jz    try_5
  351.     jmp    not_the_reset_pattern
  352. try_5:
  353.     inc    dx
  354.     in    al, dx            ; check DLCR4
  355.     and    al, 0Fh
  356.     cmp    al, 06h
  357.      je    try_6
  358.     jmp    not_the_reset_pattern
  359. try_6:
  360.     inc    dx
  361.     in    al, dx            ; check DLCR5
  362.     cmp    al, 041h
  363.      je    try_7
  364.     jmp    not_the_reset_pattern
  365. try_7:
  366.     inc    dx
  367.     in    al, dx            ; check DLCR6
  368.     cmp    al, 0B6h
  369.      je    try_8
  370.     jmp    not_the_reset_pattern
  371. try_8:
  372.     inc    dx
  373.     in    al, dx            ; check DLCR7
  374.     cmp    al, 0E0h
  375.      jne    not_the_reset_pattern
  376.  
  377.     ;  The pattern matches the AT-1700 reset pattern!
  378. found_it:
  379.     clc
  380.     pop    dx
  381.     pop    ax
  382.     ret
  383.  
  384. not_the_reset_pattern:
  385.     ;  The board at this I/O address (if there indeed is a board here)
  386.     ;  does not match the AT-1700 reset pattern.  Perhaps a driver has
  387.     ;  already been invoked which has changed some of the registers.
  388.     ;  So, we'll have to now follow Fujitsu's algorithm, which just checks
  389.     ;  a few registers to make sure a few reserved bits are actually zero.
  390.     ;  Since we don't think this approach is by itself very robust, we also
  391.     ;  add a check of DLCR6 and DLCR7 to make sure they make sense for this
  392.     ;  particular implementation (an AT-1700 always has 32k, for example).
  393.     mov    DX, DI
  394.     inc    DX
  395.     inc    DX
  396.     in    AL, DX            ; read DLCR2
  397.     and    AL, 71h            ; isolate reserved bits
  398.      jnz    not_there        ;   not zeros as expected
  399.     inc    DX
  400.     inc    DX
  401.     in    AL, DX            ; read DLCR4
  402.     and    AL, 08h            ; isolate reserved bit
  403.      jnz    not_there        ;   not zero as expected
  404.     inc    DX
  405.     in    AL, DX            ; read DLCR5
  406.     and    AL, 80h            ; isolate reserved bit
  407.      jnz    not_there        ;   not zero as expected
  408.     inc    DX
  409.     in    AL, DX            ; read DLCR6
  410.     and    AL, 0F0h        ; isolate AT-1700 meaningful bits
  411.     cmp    AL, 050h        ; known pattern for an AT-1700
  412.      jne    not_there        ;   not an (initialized) AT-1700
  413.     inc    DX
  414.     in    AL, DX            ; read DLCR7
  415.     and    AL, 020h        ; isolate AT-1700 meaningful bit
  416.     cmp    AL, 020h        ; known pattern for an AT-1700
  417.      jne    not_there        ;   not an (initialized) AT-1700
  418.  
  419.     ;  So far, it looks like this *might* be an (initialized) AT-1700.
  420.     ;  But we'll do two more checks to be sure:
  421.     ;    (1) the JLC (JumperLess Configuration) register better
  422.     ;        have an I/O base value corresponding to the I/O base
  423.     ;        that we're currently probing, and
  424.     ;    (2) the Node ID registers (DLCR8-10) better contain our magic
  425.     ;        cookie (0000F4).  This assumes that since the other regs
  426.     ;        are not in a reset state then some driver must have done
  427.     ;        something, and any reasonable driver would also load the
  428.     ;        MAC address into the Node ID regs.  This test also does
  429.     ;        something we do nowhere else while probing:  it must write
  430.     ;        registers in order to read the Node ID.  Although we don't
  431.     ;        like doing random writes, we assume that it must be fairly
  432.     ;        safe to do so since at this point we have passed all of the
  433.     ;        above tests.
  434.     call    Verify_JLC        ; do a sanity check on the JLC
  435.  
  436.     push    CX
  437.     pushf
  438.     cli                ; disable interrupts in case driver up!
  439.     mov    DX, DI
  440.     add    DX, DLCR7_OFFSET-1
  441.     in    AL, DX            ; read DLCR6
  442.     mov    CL, AL            ; save DLCR6 value for later restore
  443.     or    AL, 80h
  444.     out    DX, AL            ; enable the Node ID registers
  445.     inc    DX
  446.     in    AL, DX            ; read DLCR7
  447.     mov    CH, AL            ; save DLCR7 value for later restore
  448.     and    AL, 0F3h
  449.     out    DX, AL            ; switch to bank zero (DLCR0-DLCR15)
  450.  
  451.     inc    DX
  452.     in    AL, DX            ; read DLCR8 = Node ID [0]
  453.     cmp    AL, 00h
  454.      jne    not_a_1700        ;   not 0000F4!!
  455.     inc    DX
  456.     in    AL, DX            ; read DLCR9 = Node ID [1]
  457.     cmp    AL, 00h
  458.      jne    not_a_1700        ;   not 0000F4!!
  459.     inc    DX
  460.     in    AL, DX            ; read DLCR10 = Node ID [2]
  461.     cmp    AL, 0F4h
  462.      jne    not_a_1700        ;   not 0000F4!!
  463.  
  464.     mov    DX, DI
  465.     add    DX, DLCR7_OFFSET-1
  466.     mov    AL, CL            ; get saved DLCR6 value
  467.     out    DX, AL            ; restore DLCR6 for the driver
  468.     inc    DX
  469.     mov    AL, CH            ; get saved DLCR7 value
  470.     out    DX, AL            ; restore DLCR7 for the driver
  471.     popf                ; re-enable interrupts if appropriate
  472.     pop    CX
  473.  
  474.     jmp    found_it        ; this is apparently an AT-1700 !!!
  475.  
  476. not_a_1700:
  477.     popf                ; re-enable interrupts if appropriate
  478.     pop    CX
  479.  
  480. not_there:
  481.     stc
  482.     pop    dx
  483.     pop    ax
  484.     ret
  485.  
  486. is_there_AT1700 ENDP
  487.  
  488.  
  489. ;************************************************************************;
  490. ;*                                    *;
  491. ;*  read_mac_addr                            *;
  492. ;*    Function: to read the mac address of the board.            *;
  493. ;*    Input:    DS:(E)SI => caller's buffer where to place mac address.    *;
  494. ;*        DI = base I/O address of the AT-1700 board        *;
  495. ;*    Output: the board's MAC address is placed in the caller's bfr.    *;
  496. ;*        registers used are preserved                *;
  497. ;*                                    *;
  498. ;************************************************************************;
  499.  
  500. read_mac_addr    proc    near
  501.  
  502.     push    ax            ; save caller's registers
  503.     push    bx
  504.  
  505.     mov    bx, ETHERNET_ADDR    ; start from EEPROM location 8
  506.     call    rd_oper            ; read a word of the MAC address
  507.     mov    word ptr [CONFIG_PTR], ax
  508.     inc    bx
  509.     call    rd_oper
  510.     mov    word ptr [CONFIG_PTR+2], ax
  511.     inc    bx
  512.     call    rd_oper
  513.     mov    word ptr [CONFIG_PTR+4], ax
  514.  
  515.     pop    bx            ; restore caller's registers
  516.     pop    ax
  517.     ret                ; return to caller
  518.     
  519. read_mac_addr    endp
  520.  
  521.  
  522. ;************************************************************************;
  523. ;*                                    *;
  524. ;*  read_BMPR_val                            *;
  525. ;*    Function: read the BMPR13 value to be used from EEPROM.         *;
  526. ;*    Input:    DI = base I/O address of the AT-1700 board        *;
  527. ;*    Output: AX = BMPR13 value to be used by the driver.        *;
  528. ;*        registers used are preserved                *;
  529. ;*                                    *;
  530. ;************************************************************************;
  531.  
  532. read_BMPR_val    proc    near
  533.  
  534.     push    bx
  535.     mov    bx, BMPR13_ADDR        ; read location 24 for BMPR13
  536.     call    rd_oper
  537.     pop    bx
  538.     ret                ; return to caller
  539.  
  540. read_BMPR_val    endp
  541.  
  542.  
  543. ;************************************************************************;
  544. ;*                                    *;
  545. ;*  rd_oper                                *;
  546. ;*    Function: do a complete word READ operation.            *;
  547. ;*    Input:    BX = EEPROM address to be read.                *;
  548. ;*        DI = base I/O address of the AT-1700 board        *;
  549. ;*    Output: AX = EEPROM data from the specified location.        *;
  550. ;*        registers used are preserved                *;
  551. ;*                                    *;
  552. ;************************************************************************;
  553.  
  554. rd_oper    proc    near
  555.  
  556.     push    bx        ; save caller's registers
  557.     push    dx
  558.  
  559.     or    bl, READ
  560.     call    wr_command    ; output the address to be read
  561.     call    rd_byte        ; read the first (low-order) byte
  562.     mov    dl, al        ; temporarily save low-order byte
  563.     call    rd_byte        ; read the second (high-order) byte
  564.     mov    dh, al        ; assemble the complete word
  565.     mov    ax, dx        ;   and return to caller in AX
  566.  
  567.     pop    dx        ; restore caller's registers
  568.     pop    bx
  569.     ret            ; return to caller
  570.  
  571. rd_oper    endp
  572.  
  573.  
  574. ;************************************************************************;
  575. ;*                                    *;
  576. ;*  rd_byte                                *;
  577. ;*    Function: Read one byte from the EEPROM.            *;
  578. ;*    Input:    DI = base I/O address of the AT-1700 board        *;
  579. ;*    Output:    AL = byte read.                        *;
  580. ;*        registers used are preserved                *;
  581. ;*                                    *;
  582. ;************************************************************************;
  583.  
  584. rd_byte    proc    near
  585.  
  586.     push    cx            ; save caller's registers
  587.     push    dx
  588.  
  589.     mov    dx, DI
  590.     add    dx, EESKCS_OFFSET    ; DX = EtherCoupler EESKSC register
  591.     mov    cx, 8
  592. r_bit:
  593.     mov    al, CHIP_SEL
  594.     out    dx, al            ; turn on CHIP SELECT with CLOCK low
  595.     or    al, CLOCK
  596.     out    dx, al            ; make CLOCK go high
  597.     inc    dx            ; DX = EtherCoupler EEDP register
  598.     in    al, dx            ; read EEDP
  599.     shl    ax, 1            ; shift AH <<= 1;  AL b7 -> AH b0;
  600.     dec    dx            ; DX = EESKSC register again
  601.     loop    r_bit            ; loop to read all 8 bits
  602.  
  603.     mov    al, ah            ; return read byte (now in AH) in AL
  604.     pop    dx            ; restore caller's registers
  605.     pop    cx
  606.     ret                ; return to caller
  607.  
  608. rd_byte    endp
  609.  
  610.  
  611. ;************************************************************************;
  612. ;*                                    *;
  613. ;*  wr_command                                *;
  614. ;*    Function: Output a command and memory address to the EEPROM.    *;
  615. ;*    Input:    BL = the command/address byte to be written.        *;
  616. ;*        DI = base I/O address of the AT-1700 board        *;
  617. ;*    Output: nothing                            *;
  618. ;*        registers used are preserved                *;
  619. ;*                                    *;
  620. ;************************************************************************;
  621.  
  622. wr_command    proc    near
  623.  
  624.     push    ax            ; save caller's registers
  625.     push    dx
  626.  
  627.     mov    dx, DI
  628.     add    dx, EESKCS_OFFSET    ; DX = EtherCoupler EESKSC register
  629.     xor    al, al
  630.     out    dx, al            ; turn off CHIP SELECT and CLOCK
  631.     inc    dx            ; DX = EtherCoupler EEDP register
  632.     out    dx, al            ; clear the Serial Data In line
  633.  
  634.     dec    dx            ; DX = EESKSC register again
  635.     mov    al, CHIP_SEL
  636.     out    dx, al            ; turn on CHIP SELECT with CLOCK low
  637.     inc    dx            ; DX = EEDP register again
  638.     mov    al, SB
  639.     out    dx, al            ; write a start bit
  640.     dec    dx            ; DX = EESKSC register again
  641.     mov    al, CHIP_SEL or CLOCK
  642.     out    dx, al            ; make CLOCK go high
  643.  
  644.     call    wr_byte            ; write the caller's data byte
  645.  
  646.     pop    dx            ; restore caller's registers
  647.     pop    ax
  648.     ret                ; return to caller
  649.  
  650. wr_command    endp
  651.  
  652. ;************************************************************************;
  653. ;*                                    *;
  654. ;*  wr_byte                                *;
  655. ;*    Function: Write a byte to the eeprom.                *;
  656. ;*    Input:    BL = data byte to be written                *;
  657. ;*        DI = base I/O address of the AT-1700 board        *;
  658. ;*    Output: nothing                            *;
  659. ;*        registers used are preserved                *;
  660. ;*                                    *;
  661. ;************************************************************************;
  662.  
  663. wr_byte    proc    near
  664.  
  665.     push    ax            ; save caller's registers
  666.     push    cx
  667.     push    dx
  668.  
  669.     mov    ax, bx            ; save caller's byte temporarily
  670.     mov    dx, DI
  671.     add    dx, EEDP_OFFSET        ; DX = EtherCoupler EEDP register
  672.     mov    cx, 8
  673. s_bit:
  674.     push    ax            ; save caller's byte on the stack
  675.     out    dx, al            ; output low-order bit of caller's byte
  676.     dec    dx            ; DX = EtherCoupler EESKSC register
  677.     mov    al, CHIP_SEL
  678.     out    dx, al            ; turn on CHIP SELECT with CLOCK low
  679.     or    al, CLOCK
  680.     out    dx, al            ; make CLOCK go high
  681.     inc    dx            ; DX = EEDP register again
  682.     pop    ax            ; restore caller's saved byte from stack
  683.     shl    ax, 1            ; shift to next bit position
  684.     loop    s_bit            ; loop to output all 8 bits
  685.  
  686.     pop    dx            ; restore caller's registers
  687.     pop    cx
  688.     pop    ax
  689.     ret                ; return to caller
  690.  
  691. wr_byte    endp
  692.  
  693.  
  694. CODESEG    ENDS
  695.  
  696.