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

  1. PAGE ,132
  2. version    equ    1
  3. ;History:106,1
  4.  
  5. ;  Russell Nelson, Clarkson University.
  6. ;  Copyright, 1988-1991, Russell Nelson
  7. ;  The following people have contributed to this code: David Horne, Eric
  8. ;  Henderson, and Bob Clements.
  9.  
  10. ;   This program is free software; you can redistribute it and/or modify
  11. ;   it under the terms of the GNU General Public License as published by
  12. ;   the Free Software Foundation, version 1.
  13. ;
  14. ;   This program is distributed in the hope that it will be useful,
  15. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. ;   GNU General Public License for more details.
  18. ;
  19. ;   You should have received a copy of the GNU General Public License
  20. ;   along with this program; if not, write to the Free Software
  21. ;   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  
  23. ; Modified 910516 by Glenn Talbott, Hewlett-Packard Roseville Networks
  24. ; Division, to support the HP 27247A assembly number 27247-60002. This
  25. ; new version of the HP 27247A has a jumper which allows operation in PCs
  26. ; which violate the ISA specification for IOCHRDY by expecting the card
  27. ; to assert IOCHRDY early (actually before the card can fully decode the
  28. ; IO Address). This change does not affect this driver, however the following
  29. ; changes do.
  30. ;
  31. ; The card ID byte changes from 0x81 to 0x91.
  32. ;
  33. ; Added support for interrupt IRQ numbers 10 and 11.
  34. ;
  35. ; Comments in this code refer to 27247 rev 1.
  36.  
  37.     include    defs.asm
  38.  
  39. code    segment    word public
  40.     assume    cs:code, ds:code
  41.  
  42. ;*****************************************************************************
  43. ;
  44. ;    hppclan controller board offsets
  45. ;    IO port definition (BASE in io_addr)
  46. ;*****************************************************************************
  47. NE_DATAPORT    EQU    0ch        ; hppclan Port Window.
  48. HP_PROM        equ    00h
  49. HP_OPTION    equ    08h
  50. EN_OFF        equ    10h
  51.  
  52. ENDCFG_BM8    equ    48h
  53.  
  54. OPTION_RUN    equ    01h
  55. OPTION_DATA    equ    10h
  56.  
  57.     include    8390.inc
  58.  
  59. ; Shared memory management parameters
  60.  
  61. SM_TSTART_PG    EQU    0h        ; First page of TX buffer
  62. SM_RSTART_PG    EQU    6h        ; start at page 6
  63. ifndef debugxx
  64. SM_RSTOP_PG    EQU    80h        ; end at page 80
  65. ; add larger memory constant for 16 bit cards - gft - 910528
  66. SM_RSTOP_PG16    EQU    0FFh        ; end at page 0xff if 16 bit card
  67. else
  68. ; Make problems occur sooner and faster by having a smaller ring
  69. ; - gft - 910618
  70. SM_RSTOP_PG    EQU    1fh
  71. SM_RSTOP_PG16    EQU    1fh
  72. endif
  73.  
  74. pause_    macro
  75. ;    jmp    $+2
  76. ;
  77. ; The reason for the pause_ macro is to establish a minimum time between
  78. ; accesses to the card hardware. The assumption is that the fetch and execution
  79. ; of the jmp $+2 instruction will provide this time. In a fast cache machine
  80. ; this may be a false assumption. In a fast cache machine, there may be 
  81. ; NO REAL TIME DIFFERENCE between the two I/O instruction streams below:
  82. ;
  83. ;    in    al,dx        in    al,dx
  84. ;    jmp    $+2
  85. ;    in    al,dx        in    al,dx
  86. ;
  87. ; To establish a minimum delay, an I/O instruction must be used. A good rule of
  88. ; thumb is that ISA I/O instructions take ~1.0 microseconds and MCA I/O
  89. ; instructions take ~0.5 microseconds. Reading the NMI Status Register (0x61)
  90. ; is a good way to pause on all machines.
  91. ;
  92. ; The National 8390 Chip (NIC) requires 4 bus clocks between successive
  93. ; chip selects (National DP8390 Data Sheet Addendum, June 1990 -- it took them
  94. ; long enough to figure this out and tell everyone) or the NIC behaves badly.
  95. ; Therefor one I/O instruction should be inserted between each successive
  96. ; NIC I/O instruction that could occur 'back - to - back' on a fast cache
  97. ; machine.
  98. ;   - gft - 910529
  99. ;
  100.     push    ax
  101.     in    al, 61h
  102.     pop    ax
  103. ;
  104. endm
  105.  
  106. mc_chan_on    macro
  107.     mov    al,chan_sel
  108.     mov    dx,96h
  109.     out    dx,al            ; select channel
  110.  
  111.     mov    dx,94h
  112. ; See comments where 94h is used below - gft - 911220
  113. ;    mov    al,0a0h
  114.     mov    al,0ffh
  115.     out    dx,al            ; protect system board
  116.  
  117.     mov    dx,102h            ; point dx at option reg
  118. endm
  119.  
  120. mc_chan_off    macro
  121.     mov    dx,96h
  122.     xor    al,al
  123.     out    dx,al
  124. endm
  125.  
  126. reset_8390    macro
  127.     local   is_mc_b
  128.     local    not_mc_c
  129.     local    not_mc_d
  130.  
  131.     test    sys_features,SYS_MCA
  132.     jne    is_mc_b
  133.     jmp    not_mc_c
  134. is_mc_b:
  135.     mc_chan_on
  136.     in    al,dx            ;capture and save option register
  137.     and    al, not OPTION_RUN    ;reset the 8390
  138.     out    dx,al
  139.     longpause
  140.     or    al, OPTION_RUN        ;turn it back on
  141.     out    dx,al        
  142.     mc_chan_off
  143.     loadport            ;Set DX the way we expect it
  144.     setport    HP_OPTION        
  145.     jmp    not_mc_d
  146.  
  147. not_mc_c:
  148.     loadport
  149.     setport    HP_OPTION        ;hard reset 8390.
  150.     xor    al,al            ;reset the 8390
  151.     out    dx,al
  152.     longpause
  153.  
  154. ; Revised int_no setting to use table lookup for 27247 rev 1
  155.  
  156.     push    bx        ;paranoia?
  157.     xor    bh,bh            ;clear high half of bx
  158.     mov    bl,int_no        ;get the index
  159.     add     bx,cs:int_bits        ;add the address of table
  160.                 ; the superfluous segment override prevents
  161.                 ; one of those #$%^&! phase errors in MASM
  162.     mov    al,byte ptr [bx]    ;properly adjusted bits for int_no
  163.     or    al, OPTION_RUN        ;turn it back on
  164.     out    dx,al        
  165.     pop    bx
  166.  
  167. not_mc_d:
  168.     endm
  169.  
  170. terminate_board    macro
  171.     local is_mc_a
  172.     local not_mc_a
  173.     local not_mc_b
  174.     test    sys_features,SYS_MCA
  175.     jne    is_mc_a
  176.     jmp    not_mc_a
  177.  
  178. is_mc_a:
  179. ; I can't believe this ever worked right, so it's probably not necessary
  180. ; to put the card into reset for a terminate. Never the less the 
  181. ; call to the mc_chan_on macro was missing from here - gft - 910529
  182. ;
  183. ; New comment: When I wrote the above 910529 comment I couldn't figure out
  184. ; how it ever worked, now I know; It never did. In a microchannel machine
  185. ; the system boots and the option register is set with the proper IRQ, I/O 
  186. ; address, and OPTION_RUN on by system initialization code. When we terminate
  187. ; the packet driver we leave the OPTION_RUN bit OFF. When the OPTION_RUN bit
  188. ; is OFF you can't read the station address from ROM, hence the code which
  189. ; identifies the card fails! Therefor you can't ever re-start the packet 
  190. ; driver after a terminate!
  191. ;
  192. ; To fix this, and leave the card in the same state as at bootup, I modified
  193. ; the below code to reset, then restore the option register for MCA machines.
  194. ;
  195. ; - gft - 910610
  196. ;
  197.     mc_chan_on
  198.     in    al,dx            ;capture and save option register
  199.     and    al, not OPTION_RUN    ;reset the 8390
  200.     out    dx,al
  201.     longpause
  202.     or    al, OPTION_RUN        ;turn the card back on for future access
  203.     out    dx,al
  204.     mc_chan_off
  205.     loadport            ;Set DX the way we expect it
  206.     setport    HP_OPTION        
  207.     jmp    not_mc_b
  208.  
  209. not_mc_a:
  210.     loadport
  211.     setport    HP_OPTION        ;hard reset 8390.
  212.     xor    al,al
  213.     out    dx,al
  214. not_mc_b:
  215.     endm
  216.  
  217.     extrn    sys_features: byte
  218.  
  219.     extrn    set_recv_isr: near
  220.  
  221. ;enter with si -> argument string, di -> word to store.
  222. ;if there is no number, don't change the number.
  223.     extrn    get_number: near
  224.  
  225. ;enter with dx -> name of word, di -> dword to print.
  226.     extrn    print_number: near
  227.  
  228. ;enter with al = single character
  229.     extrn    chrout: near
  230.  
  231.     public    int_no, io_addr
  232. int_no        db    3,0,0,0        ;must be four bytes long for get_number.
  233. io_addr        dw    0300h,0        ; I/O address for card (jumpers)
  234.  
  235.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  236. driver_class    db    BLUEBOOK, IEEE8023, 0        ;from the packet spec
  237. driver_type    db    ?        ;Wild card matches any type
  238. driver_name    db    "HP ",20 dup(?)    ;name of the driver.
  239. driver_function    db    2
  240. parameter_list    label    byte
  241.     db    1    ;major rev of packet driver
  242.     db    9    ;minor rev of packet driver
  243.     db    14    ;length of parameter list
  244.     db    EADDR_LEN    ;length of MAC-layer address
  245.     dw    GIANT    ;MTU, including MAC headers
  246.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  247.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  248.     dw    0    ;(# of successive xmits) - 1
  249. int_num    dw    0    ;Interrupt # to hook for post-EOI
  250.             ;processing, 0 == none,
  251.  
  252.     extrn    is_186: byte        ;=0 if 808[68], =1 if 80[123]86.
  253.  
  254. chan_sel    db    0    ;Channel select for SYS_MCA machines
  255.  
  256. ;    Block input routine
  257. ;    CX = byte count, es:si = buffer location, ax = buffer address
  258.  
  259.     public    block_input
  260. block_input:
  261.     push    ax            ; save buffer address
  262.  
  263.     loadport
  264.     setport    HP_OPTION        
  265.     test    sys_features,SYS_MCA
  266.     je    not_mc_1
  267.     jmp    is_mc_1
  268. not_mc_1:
  269.     in    al,dx
  270.     or    al,OPTION_DATA        ;Enable the data port except on MCA
  271.     out    dx,al
  272.  
  273. is_mc_1:
  274.     setport EN_CCMD
  275.     pause_
  276.     mov    al,ENC_NODMA+ENC_PAGE0+ENC_START
  277.     out    dx,al
  278.     setport    EN0_RCNTLO    ; remote byte count 0
  279.     pause_
  280.     mov    al,cl
  281.     out    dx,al
  282.     setport    EN0_RCNTHI
  283.     pause_
  284.     mov    al,ch
  285.     out    dx,al
  286.     pop    ax        ; get our page back
  287.     setport    EN0_RSARLO
  288.     pause_
  289.     out    dx,al        ; set as hi address
  290.     setport    EN0_RSARHI
  291.     pause_
  292.     mov    al,ah
  293.     out    dx,al
  294.     setport EN_CCMD
  295.     pause_
  296.     mov    al,ENC_RREAD+ENC_START    ; read and start
  297.     out    dx,al
  298.     setport    NE_DATAPORT
  299.     pause_
  300.     cmp    is_186,0
  301.     jnz    read_186
  302.     shr    cx,1
  303. read_loop:
  304.     in    ax,dx        ; get a word
  305.     stosw            ; save it
  306.     loop    read_loop
  307.     jnc    read_done
  308.     in    al,dx
  309.     stosb
  310.     jmp    short read_done
  311. read_186:
  312.     shr    cx,1
  313.     .286
  314.     rep    insw
  315.     jnc    read_done
  316.     insb
  317. read_done:
  318.     .8086
  319.     setport    HP_OPTION
  320.     test    sys_features,SYS_MCA
  321.     je    not_mc_2
  322.     ret
  323. not_mc_2:
  324.     in    al,dx
  325.     and    al,not OPTION_DATA
  326.     out    dx,al
  327.     ret
  328. ;
  329. ;    Block output routine
  330. ;    CX = byte count, ds:si = buffer location, ax = buffer address
  331.  
  332.  
  333. block_output:
  334.     assume    ds:nothing
  335.     push    ax        ; save buffer address
  336.  
  337.     loadport
  338.     setport    HP_OPTION
  339.     test    sys_features,SYS_MCA
  340.     je    not_mc_3
  341.     jmp    is_mc_3
  342. not_mc_3:
  343.     in    al,dx
  344.     or    al,OPTION_DATA    ; enable the data port except on MCA
  345.     out    dx,al
  346.  
  347. is_mc_3:
  348.     inc    cx        ; make even
  349.     and    cx,0fffeh
  350.     setport EN_CCMD
  351.     pause_
  352.     mov    al,ENC_NODMA+ENC_START
  353.     out    dx,al        ; stop & clear the chip
  354.  
  355. ; To quote from the National DP8390 Datasheet Addendum, June 1990
  356. ;
  357. ;   11.0 Remote DMA Write
  358. ;
  359. ;   Under certain conditions the NIC may issue /MWR and /PRD before
  360. ;   PRQ for the first DMA transfer. This causes an extraneous byte to be
  361. ;   written inot memory at the first Remote DMA Write location. [...]
  362. ;
  363. ;   To prevent this condition, write a non-zero value into RBCR0 and 
  364. ;   issued [sic] the Remote Read DMA command to the NIC (CR=0AH), but
  365. ;   do not give any Read Acknowledges (/RACK). (This causes PRQ to go high.)
  366. ;   Then write the desired byte count into RBCR0 and RBCR1 and give the 
  367. ;   Remote Write DMA command (CR=12H). The Remote Write DMA will operate as
  368. ;   normal.
  369. ;
  370. ; My interpretation of the above is          - gft - 910603
  371.  
  372.     
  373.     setport    EN0_RCNTLO    ; remote byte count 0
  374.     pause_
  375.     mov    al,0ffh        ; a non-zero value
  376.     out    dx,al
  377.     setport EN_CCMD
  378.     pause_
  379.     mov     al,ENC_RREAD+ENC_START ; read and start
  380.     out     dx,al        ; starts the read setting PRQ for the first
  381.                 ; DMA transfer, now reprogram everything
  382.                 ; and start a write instead.
  383.  
  384. ;
  385. ; BUT WHAT THE NATIONAL DOCUMENTATION DOESN'T TELL YOU ...
  386. ;
  387. ;  When the read is started, the remote byte count register is decremented
  388. ;  (in this case from 0ffh to 0feh). This takes a finite amount of time. 
  389. ;  IF you are TOO QUICK in re-programming the remote byte count 0 register
  390. ;  to the correct value, the NEW VALUE GETS DECREMENTED INSTEAD! Then when
  391. ;  you reach the last byte of the buffer and you output it to the IO port,
  392. ;  the NIC has already reached a count of zero and WON'T HANDSHAKE THE LAST
  393. ;  BYTE!. Result, computer HUNG, powercycle to recover. Therefore a stall is 
  394. ;  required here, I use at least 1.5uS
  395. ;                                      - gft - 910603
  396. ;
  397.     in    al,61h        ; read from NMI Status register for IO delay
  398.     in    al,61h        ; ~ 0.5uS on Microchannel and ~ 1.0 on ISA
  399.     in    al,61h        ; for a total of ~1.5uS or 3.0uS.
  400.  
  401. ; we now return you to your regularly scheduled block_output routine.
  402.  
  403.     setport    EN0_RCNTLO    ; remote byte count 0
  404.     pause_
  405.     mov    al,cl
  406.     out    dx,al
  407.     setport    EN0_RCNTHI
  408.     pause_
  409.     mov    al,ch
  410.     out    dx,al
  411.     pop    ax        ; get our page back
  412.     setport    EN0_RSARLO
  413.     pause_
  414.     out    dx,al        ; set as lo address
  415.     setport    EN0_RSARHI
  416.     pause_
  417.     mov    al,ah
  418.     out    dx,al
  419.     setport EN_CCMD
  420.     pause_
  421.     mov    al,ENC_RWRITE+ENC_START    ; write and start
  422.     out    dx,al
  423.     setport    NE_DATAPORT
  424.     pause_
  425.     shr    cx,1
  426.     cmp    is_186,0
  427.     jnz    write_186
  428. write_loop:
  429.     lodsw            ; get a word
  430.     out    dx,ax        ; save it
  431.     loop    write_loop
  432.     jmp    short write_done
  433. write_186:
  434.     .286
  435.     rep    outsw
  436.     .8086
  437. write_done:
  438.     mov    cx,0
  439.     setport    EN0_ISR
  440. tx_check_rdc:
  441.     in    al,dx
  442.     test    al,ENISR_RDC    ; dma done ???
  443.     clc
  444.     jnz    tx_start
  445.     loop    tx_check_rdc
  446.     stc
  447. tx_start:
  448.     setport    HP_OPTION
  449.     test    sys_features,SYS_MCA
  450.     je    not_mc_4
  451.     ret
  452. not_mc_4:
  453.     lahf                ;save cy.
  454.     in    al,dx
  455.     and    al,not OPTION_DATA
  456.     out    dx,al
  457.     sahf                ;restore cy.
  458.     ret
  459.  
  460.     include    8390.asm
  461.  
  462.     public    usage_msg
  463. usage_msg    db    "usage: hppclan [options] <packet_int_no> <hardware_irq> <io_addr>",CR,LF,'$'
  464.  
  465.     public    copyright_msg
  466. copyright_msg    db    "Packet driver for HP PC LAN cards, version "
  467.         db    '0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,".",'0'+dp8390_version,CR,LF,'$'
  468.  
  469. no_hp_msg    db    "No HP PC LAN card found (matching io_addr or int_no if spedified).",CR,LF,'$'
  470. cfg_err_msg    db    "Configuration failed. Check parameters.",CR,LF,'$'
  471. int_no_name    db    "Interrupt number ",'$'
  472. io_addr_name    db    "I/O port ",'$'
  473.  
  474. comment \
  475.  
  476. Here are the ID byte values for all released cards.  Bit 7 of the ID byte
  477. for AT cards indicates bus width (as well as RAM buffer size).
  478.  
  479. The ID byte was added to give a unique number to every revision of every card
  480. produced.  However, it is a little more than just a flat assignment; there is
  481. some fields.  For driver software it is assumed the driver knows what bus it
  482. is on (eg. AT verses MC):
  483.  
  484. The format of the ID byte (offset 0x07 from I/O base) is:
  485.  
  486.         7  6  5  4  3  2  1  0
  487.         a  b  b  b  c  c  c  c
  488. where,
  489.         "a"   is the AT bus width bit
  490.          0 =  8 bit AT cards (32K bytes of buffer RAM)
  491.          1 = 16 bit AT cards (64K bytes of buffer RAM)
  492.  
  493.         "bbb" is for board revisions
  494.  
  495.         "ccc" is the LAN Media type
  496.          000 = HP StarLAN-10
  497.          001 = 10-Base-T (Ethertwist)
  498.          002 = 10-Base-2 (ThinLAN)
  499.          ??? = reserved for future
  500.  
  501. The current ID bytes assigned are:
  502.         0x00 = (obsolete) HP27240 AT8  StarLAN
  503.         0x10 = (obsolete) HP24240 AT8  StarLAN rev B
  504.         0x00 = (obsolete) HP27241 MC16 StarLAN
  505.         0x01 = HP27245 AT8  10-Base-T
  506.         0x01 = HP27246 MC16 10-Base-T
  507.         0x02 = HP27250 AT8  ThinLAN
  508.         0x81 = HP27247 AT16 10-Base-T
  509.         0x91 = HP27247 AT16 10-Base-T rev 1
  510.  
  511. NOTE:   All Microchannel cards are 16 bits wide.
  512.         All 8 bit cards have 32K bytes of buffer RAM.
  513.         All 16 bit cards (AT & MC) have 64K bytes of buffer RAM.
  514. \
  515.  
  516. this_board_msg    db    "This board is an HP",'$'
  517.  
  518. ISA_name_list    dw    board_00ISA, board_10, board_01ISA, board_02, board_81
  519.         dw    board_91
  520.         dw    board_unk
  521. MCA_name_list    dw    board_00MCA, board_01MCA
  522.         dw    board_unk
  523.  
  524. board_00ISA    db    00h, "27240",0,60    ;AT8  StarLAN
  525. board_10    db    10h, "24240",0,60    ;AT8  StarLAN rev B
  526. board_00MCA    db    00h, "27241",0,60    ;MC16 StarLAN
  527. board_01ISA    db    01h, "27245",0,60    ;AT8  10-Base-T
  528. board_01MCA    db    01h, "27246",0,60    ;MC16 10-Base-T
  529. board_02    db    02h, "27250",0,60    ;AT8  ThinLAN
  530. board_81    db    81h, "27247",0,60    ;AT16 10-Base-T
  531. board_91    db    91h, "27247",0,60    ;AT16 10-Base-T rev 1
  532. board_unk    db    -1h, "Unknown HP272xx",0,60    ;just a guess.
  533.  
  534. ; ISA DEFAULTS for io_addr and int_no,
  535. ; MCA DEFAULTS to first found.
  536.  
  537. DEF_IO_ADDR    equ    0300h    
  538. DEF_INT_NO    equ    3
  539.  
  540. MC_DEF_IO    equ    1
  541. MC_DEF_INT    equ    2
  542. MC_DEF_BOTH    equ    MC_DEF_IO+MC_DEF_INT
  543.  
  544. mc_def_req    db    0
  545.  
  546. int_no_table    db    3, 4, 5, 7, 9, 10, 11, 12
  547.  
  548. ; Added for 27247 rev 1, interrupt numbers are no longer simply left shifted
  549. ; one for writing into the option register. Use a lookup table instead.
  550. ; Entries of 0xff are not valid for the card.
  551.  
  552. ; Table for AT cards except 27247 rev 1
  553.  
  554. int_bits_0    db    0ffh, 0ffh, 04h, 06h, 08h, 0ah, 0ffh, 0eh ;ints 0-7
  555.         db    0ffh, 04h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh ;ints 8-f
  556.  
  557. ; Table for 27247 rev 1
  558.  
  559. int_bits_1    db    0ffh, 0ffh, 04h, 06h, 08h, 0ah, 0ffh, 0eh ;ints 0-7
  560.         db    0ffh, 04h, 02h, 0ch, 0ffh, 0ffh, 0ffh, 0ffh ;ints 8-f
  561.  
  562. int_bits    dw int_bits_0
  563.  
  564. ; First 3 bytes of the LAN Addres will identify the board as HP
  565.  
  566. hp_vendor_id    db    08h,00h,09h
  567.  
  568.     public    parse_args
  569. parse_args:
  570. ;exit with nc if all went well, cy otherwise.
  571.     test    sys_features,SYS_MCA
  572.     jne    parse_args_mc
  573.     jmp    parse_args_1
  574.  
  575. parse_args_mc:
  576.  
  577. ; first determine if non-default values have been requested
  578. ; get_number will return requested value, -1, or carry flag set
  579.  
  580.     mov    di,offset int_no
  581.     call    get_number
  582.     mov    BYTE PTR [di+1], 0
  583.     mov    WORD PTR [di+2], 0
  584.     jnc    parse_args_mc2
  585.     mov    BYTE PTR [di], 0ffh    ; error return, use -1 value
  586.  
  587. parse_args_mc2:
  588.     mov    di,offset io_addr
  589.     call    get_number
  590.     mov    WORD PTR [di+2], 0
  591.     jnc    parse_args_mc3
  592.     mov    WORD PTR [di], 0ffffh    ; error return, use -1 value
  593.  
  594. parse_args_mc3:
  595.     
  596.     xor    al,al
  597.     cmp    io_addr,0ffffh
  598.     jne    parse_args_mc4
  599.     mov    al,MC_DEF_IO
  600.  
  601. parse_args_mc4:
  602.     cmp    int_no,0ffh
  603.     jne    parse_args_mc5
  604.     or    al,MC_DEF_INT
  605.  
  606. parse_args_mc5:
  607.     mov    mc_def_req,al
  608.  
  609. ;The following code to read the POS registers is courtesy of Racal-Interlan.
  610.  
  611. ; channel selector resides at io 96h
  612. ; POS register base is at io 100h
  613.  
  614. ; search thro' the slots for a 9210 card
  615.     mov    cx, 8            ; for all channels(slots)
  616.  
  617. ; channel select value for slots 0,1,2.. is 8,9,A etc
  618. ; start with slot 0, and then 7,6,5,4,3,2,1
  619.  
  620. get_01:
  621.     mov    ax, cx            ; channel number
  622.     or    ax, 08h            ; reg. select value
  623.     mov    chan_sel,al        ; save each one, the LAST will right
  624.     mov    dx, 96h            ; channel select register
  625.     out    dx, al            ; select channel
  626.  
  627.     mov    dx, 94h            ; protect system board
  628. ; The new PS/2 Model 57 doesn't work when 0a0h is used here. The IBM BIOS
  629. ; writes a 0ffh to this register and just leaves it this way. IBM seems to
  630. ; indicate that 0ffh or 07fh should be written, but details are hard to
  631. ; come by. We have tested 0ffh in our other drivers in all the PS/2s we
  632. ; could lay our hands on, so I am fairly confident that 0ffh is OK here.
  633. ;     - gft - Hewlett-Packard - 911220
  634. ;
  635. ;    mov    al, 0a0h
  636.     mov    al, 0ffh
  637.     out    dx, al            
  638.  
  639. ; read adapter id
  640.     mov    dx, 100h
  641.     in    al, dx            ; adapter id - ms byte
  642.     mov    ah, al
  643.     inc    dx
  644.     in    al, dx            ; adapter id - ls byte
  645.  
  646. ; Check if HP
  647.     cmp    ax, 0ca63h        ;actually 63ca.
  648.     je    get_03
  649.     
  650. get_02:
  651.     ; come back to here if card found does not match user 
  652.     ; requirements below
  653.  
  654.     loop    get_01
  655.  
  656.     mc_chan_off
  657.     mov    dx,offset no_hp_msg
  658.     jmp    error
  659.  
  660. get_03:        ; found an HP adapter, is it the right one?
  661.  
  662. comment \
  663.  
  664. The only POS registers defined for the Microchannel card (HP27246) are:
  665.  
  666.         0x100 = Adapter Identification LSB (0xCA) Read only
  667.         0x101 = Adapter Identification MSB (0x63) Read only
  668.         0x102 = Option Register Read/Write
  669.  
  670. The Option register bits are defined as:
  671.  
  672.         7 6 5 4 3 2 1 0
  673.         a a a - b b b c
  674.  
  675. where,
  676.         "aaa" is the I/O Base Address Relocation bits
  677.          000 = 0x0400 to 0x041f
  678.          001 = 0x1400 to 0x141f
  679.          010 = 0x2400 to 0x241f
  680.          011 = 0x3400 to 0x341f
  681.          100 = 0x4400 to 0x441f
  682.          101 = 0x5400 to 0x541f
  683.          110 = 0x6400 to 0x641f
  684.          111 = 0x7400 to 0x741f
  685.  
  686.  
  687.         "bbb" is the Interrupt Level bits
  688.          000 = INT 3
  689.          001 = INT 4
  690.          010 = INT 5
  691.          011 = INT 7
  692.          100 = INT 9
  693.          101 = INT 10
  694.          110 = INT 11
  695.          111 = INT 12
  696.  
  697.         "c" is the Card Enable / NIC Reset bit
  698.          0 = NIC held in reset (eg. cannot access its registers)
  699.          1 = NIC not reset (eg. regster can be accessed)
  700.          NOTE: Access to the PROM should only occur while NIC is held in reset.
  701.  
  702. \
  703.  
  704.     mov    dx,102h
  705.     in    al,dx
  706.     and    ax,00e0h        ;leave only the base address bits
  707.     push    cx
  708.     mov    cl,12-5            ;now ends at bit 5, should end at bit 12
  709.     shl    ax,cl
  710.     pop    cx
  711.     or    ax,400h
  712.     mov    di,ax        ; temporary save
  713.  
  714.     in    al,dx
  715.     shr    al,1
  716.     and    al,7
  717.     mov    bl,al
  718.     xor    bh,bh
  719.     mov    al,int_no_table[bx]
  720.  
  721.     ; check for matches with user selects
  722.  
  723.     mov    ah,mc_def_req
  724.     test    ah,MC_DEF_IO
  725.     jz    get_04
  726.     mov    io_addr,di    ; user wants default, copy temp address
  727.  
  728. get_04:
  729.     test    ah,MC_DEF_INT
  730.     jz    get_05
  731.     mov    int_no,al    ; user wants default, copy temp int number
  732.  
  733. get_05:    
  734.     cmp    di,io_addr
  735.     je     get_06
  736.     jmp    get_02        ; correct io_addr not found, keep looking
  737.  
  738. get_06:    
  739.     cmp    al,int_no
  740.     je     get_07
  741.     jmp    get_02        ; correct io_addr not found, keep looking
  742.  
  743. get_07:        ; if we get here we now have the io_addr and int_no
  744.         ; that the user wanted
  745.     mc_chan_off
  746.     jmp parse_args_5
  747.  
  748. ;
  749. ; Much simpler code for ISA machine parse_args
  750. ;
  751. parse_args_1:
  752.     mov    di,offset int_no
  753.     call    get_number
  754.     jc    parse_args_2
  755.     cmp    WORD PTR [di],0
  756.     jl    parse_args_2
  757.     jmp    parse_args_3
  758.  
  759. parse_args_2:
  760.     mov    WORD PTR [di],DEF_INT_NO
  761.     mov    WORD PTR [di+2],0
  762.  
  763. parse_args_3:
  764.     mov    di,offset io_addr
  765.     call    get_number
  766.     jc    parse_args_4
  767.     cmp    WORD PTR [di],0
  768.     jl    parse_args_4
  769.     jmp    parse_args_5
  770.  
  771. parse_args_4:
  772.     mov    WORD PTR [di],DEF_IO_ADDR
  773.     mov    WORD PTR [di+2],0
  774.  
  775. parse_args_5:    ;Finally verify HP Vendor ID in 1st 3 bytes of station addr
  776.     loadport
  777.     setport    HP_PROM
  778.     mov    di,offset hp_vendor_id
  779.     mov    cx,3
  780. id_card_loop:
  781.     in    al,dx
  782.     cmp    al, BYTE PTR [di]
  783.     je    id_card_loop1
  784.     mov    dx,offset no_hp_msg
  785.     jmp    error
  786.  
  787. id_card_loop1:
  788.     inc    di
  789.     inc    dx
  790.     loop    id_card_loop
  791.  
  792. ; for 27247 rev 1, delete the next two instructions to allow inline execution
  793. ; of id_card
  794. ;    clc
  795. ;    ret
  796.  
  797.  
  798. ; for 27247 rev 1, changed this routine from "init_card" to "id_card" and 
  799. ; called it from parse_args to verify argument int_no and print out all
  800. ; the driver name. This allows full verification of int_no before init_card
  801. ; is called. init card then becomes a big NOP, but must be declared so that it
  802. ; can be called from 8390.asm
  803.  
  804. id_card:
  805. ;Read PROM contents
  806.     loadport
  807.     setport    HP_PROM
  808.     mov    di,offset rom_address
  809.     mov    ax,cs
  810.     mov    es,ax
  811.     mov    cx,EADDR_LEN
  812.     xor    ah,ah
  813. id_card_1:
  814.     in    al,dx
  815.     add    ah,al
  816.     inc    dx
  817.     stosb
  818.     loop    id_card_1
  819.     in    al,dx            ;now get the checksum.
  820.     xor    ah,al            ;add it in.
  821.     cmp    ah,-1            ;now it should have all ones set.
  822. ;ugh.  The checksum was botched on some boards, so we can't use it.
  823. ;    jne    id_card_2        ;did it match?  Nope, return error.
  824.     inc    dx
  825.     in    al,dx            ;get the hardware revision number.
  826.  
  827.     test    sys_features,SYS_MCA    ;ISA or MCA?
  828.     jne    is_16bit        ;MCA - all MCA cards are 16-bit cards.
  829.     test    al,80h            ;16-bit system?
  830.     je    check_16bit
  831.  
  832. ; Only AT 16 bit cards get here, check for extended IRQ support on 27247 rev 1
  833.  
  834.     cmp    al,91h
  835.     jne    is_16bit
  836.     mov    bx, offset int_bits_1
  837.     mov    int_bits,bx
  838.  
  839. is_16bit:
  840.     or    endcfg,ENDCFG_WTS    ;yes, use word transfer mode.
  841.  
  842. ; also use larger on-card memory for 16 bit -gft 910528
  843.  
  844.     mov    sm_rstop_ptr,SM_RSTOP_PG16
  845.  
  846. check_16bit:
  847.  
  848.     mov    bx,offset MCA_name_list        ;assume MCA
  849.     test    sys_features,SYS_MCA    ;ISA or MCA?
  850.     jne    check_board_name        ;MCA.
  851.  
  852. ; ISA board here, verify interrupt value parameter, added for 27247 rev 1
  853.  
  854.     xor    bh,bh            ; clear hi half of bx
  855.     mov    bl,int_no        ; index to the interrupt number
  856.     add    bx,int_bits        ; get pointer to proper int_bits table
  857.     cmp    byte ptr [bx],-1    ; check for not valid
  858.     jne    check_board_ISA_name    ; int_no OK
  859.     mov    dx, offset cfg_err_msg    ; int_no not valid, tough luck
  860. error:
  861.     mov    ah,9        ; Type the msg
  862.     int    21h
  863.     stc            ; Indicate error
  864.     ret            ; Return to common code
  865.  
  866. check_board_ISA_name:
  867.     mov    bx,offset ISA_name_list        ;Get the ISA name list now
  868. check_board_name:
  869.     push    si        ; for 27247 rev 1, save si
  870. check_board_name_loop:
  871.     mov    si,[bx]            ;get a pointer to a string.
  872.     add    bx,2
  873.     cmp    byte ptr [si],-1    ;is this the end?
  874.     je    check_board_found
  875.     cmp    al,[si]            ;is this the right one?
  876.     jne    check_board_name_loop
  877. check_board_found:
  878.     inc    si            ;skip the board revision number.
  879.  
  880.     mov    dx,offset this_board_msg
  881.     mov    ah,9
  882.     int    21h
  883.  
  884.     mov    ax,ds            ;copy the driver name to where
  885.     mov    es,ax            ;  we need it.
  886.     mov    di,offset driver_name+3
  887. check_board_copy:
  888.     lodsb
  889.     stosb
  890.     or    al,al
  891.     je    check_board_done_print
  892.     call    chrout            ;print the character.
  893.     jmp    check_board_copy
  894. check_board_done_print:
  895.     lodsb                ;copy the driver type number over
  896.     mov    driver_type,al
  897.     pop    si        ; for 27247 rev 1, restore si for caller
  898.     mov    al,CR
  899.     call    chrout
  900.     mov    al,LF
  901.     call    chrout
  902.  
  903.     clc
  904.     ret
  905. id_card_2:
  906.     stc
  907.     ret
  908.  
  909. ; for 27247 rev 1, new init_card: the big NOP
  910.  
  911.     extrn    etopen_diagn: byte
  912.  
  913. init_card:
  914.     clc
  915.     ret
  916.  
  917.  
  918.     public    print_parameters
  919. print_parameters:
  920. ;echo our command-line parameters
  921.     mov    di,offset int_no
  922.     mov    dx,offset int_no_name
  923.     call    print_number
  924.     mov    di,offset io_addr
  925.     mov    dx,offset io_addr_name
  926.     call    print_number
  927.     ret
  928.  
  929. code    ends
  930.  
  931.     end
  932.